diff --git a/README.OPENSOURCE b/README.OPENSOURCE index d38217aeff3564abb7411e0ff2c2b15582949e10..9e8b6095b9b6931ba054e5bbfc0ba3a82648b01c 100644 --- a/README.OPENSOURCE +++ b/README.OPENSOURCE @@ -6,7 +6,7 @@ "License": "GNU GENERAL PUBLIC License", - "License File": "FileTransfer/README.md", + "License File": "LICENSE", "Version Number": "Master", diff --git a/README.md b/README.md index fe5d01aadc1e323f18a097dc0a1a694ffb4e1998..79057173dbf998629f0555761d4ef03117a597b0 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ public class UserController { @PostMapping(path = "/upload", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) String upload(@RequestParam(name = "avatar") MultipartFile file) throws IOException { - File localFile = ...FileUtils.createRandomFile(file); - + File localFile = FileUtils.createRandomFile(file); + ... return localFile.getAbsolutePath(); } diff --git a/annotation/.gitignore b/annotation/.gitignore deleted file mode 100644 index 796b96d1c402326528b4ba3c12ee9d92d0e212e9..0000000000000000000000000000000000000000 --- a/annotation/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/annotation/build.gradle b/annotation/build.gradle deleted file mode 100644 index 88b4e2c921ce2c1e8ae92434257b7a78457799f0..0000000000000000000000000000000000000000 --- a/annotation/build.gradle +++ /dev/null @@ -1,12 +0,0 @@ -apply plugin: 'java-library' - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) -} - -sourceCompatibility = "8" -targetCompatibility = "8" - -ohos { - compileSdkVersion = 5 -} diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Addition.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Addition.java deleted file mode 100644 index 16430b9718eb794ed2fe6bd3c6f684b9ba29ff9a..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Addition.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -@Target({ElementType.METHOD}) -@Retention(RetentionPolicy.SOURCE) -public @interface Addition { - - /** - * Alias for {@link #stringType()}. - */ - String[] value() default {}; - - /** - * The added value of the String type. - */ - String[] stringType() default {}; - - /** - * The added value of the boolean type. - */ - boolean[] booleanType() default {}; - - /** - * The added value of the int type. - */ - int[] intTypeType() default {}; - - /** - * The added value of the long type. - */ - long[] longType() default {}; - - /** - * The added value of the short type. - */ - short[] shortType() default {}; - - /** - * The added value of the float type. - */ - float[] floatType() default {}; - - /** - * The added value of the double type. - */ - double[] doubleType() default {}; - - /** - * The added value of the byte type. - */ - byte[] byteType() default {}; - - /** - * The added value of the char type. - */ - char[] charType() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/AppInfo.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/AppInfo.java deleted file mode 100644 index fa9dffacb4d55c694273096ddb9fba195476e36c..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/AppInfo.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 4/11/20. - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface AppInfo { - - /** - * Application Id. - */ - String value() default ""; - -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Config.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Config.java deleted file mode 100644 index adb04ee4d09e2c4245ab750ac79cf51ae9247bdf..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Config.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2019 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/9. - *
- * @Config
- * public class AppConfig implements WebConfig {
- *
- *     @Override
- *     public void onConfig(Context context, Delegate delegate) {
- *         Website website = ...;
- *         delegate.addWebsite(website);
- *
- *         Multipart multipart = Multipart.newBuilder()...build();
- *         delegate.setMultipart(multipart);
- *     }
- * }
- * 
- */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface Config { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Controller.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Controller.java deleted file mode 100644 index 52cec7ef9e97d13f04df5fc36ac1f3a06e5ad567..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Controller.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface Controller { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Converter.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Converter.java deleted file mode 100644 index 13b0e06d8294ba2a96b65386aeb7b26f653febe8..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Converter.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface Converter { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CookieValue.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CookieValue.java deleted file mode 100644 index c61278d3f7a168de3c3ed16ec8549c671a2b027f..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CookieValue.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface CookieValue { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the cookie to bind to. - */ - String name() default ""; - - /** - * Whether the cookie is required. - * - *

Defaults to {@code true}, leading to an exception being thrown if the cookie is missing in the request. Switch - * this to {@code false} if you prefer a {@code null} value if the cookie is not present in the request. - * - *

Alternatively, provide a {@link #defaultValue()}, which implicitly sets this flag to {@code false}. - */ - boolean required() default true; - - /** - * The default value to use as a fallback. - * - *

Supplying a default value implicitly sets {@link #required()} to {@code false}. - */ - String defaultValue() default ""; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CrossOrigin.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CrossOrigin.java deleted file mode 100644 index c7acfadb503a6a4796e9ab28f225a892cc8f1550..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/CrossOrigin.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 10/10/20. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface CrossOrigin { - - /** - * Alias for {@link #origins()}. - */ - String[] value() default {}; - - /** - * List of allowed origins, e.g. {@code "http://domain1.com"}. - * - *

These values are placed in the {@code Access-Control-Allow-Origin} - * header of both the pre-flight response and the actual response. - * {@code "*"} means that all origins are allowed. - * - *

If undefined, all origins are allowed. - * - * @see #value() - */ - String[] origins() default {}; - - /** - * List of request headers that can be used during the actual request. - * - *

This property controls the value of the pre-flight response's - * {@code Access-Control-Allow-Headers} header. - * {@code "*"} means that all headers requested by the client are allowed. - * - *

If undefined, all requested headers are allowed. - */ - String[] allowedHeaders() default {}; - - /** - * List of response headers that the user-agent will allow the client to access. - * - *

This property controls the value of actual response's - * {@code Access-Control-Expose-Headers} header. - * - *

If undefined, an empty exposed header list is used. - */ - String[] exposedHeaders() default {}; - - /** - * List of supported HTTP request methods, e.g. - * {@code "{RequestMethod.GET, RequestMethod.POST}"}. - * - *

Methods specified here override those specified via {@code RequestMapping}. - * - *

If undefined, methods defined by {@link RequestMapping} annotation are used. - */ - RequestMethod[] methods() default {}; - - /** - * Whether the browser should include any cookies associated with the - * domain of the request being annotated. - * - *

Set to {@code "false"} if such cookies should not included. - * An empty string ({@code ""}) means undefined. - * {@code "true"} means that the pre-flight response will include the header - * {@code Access-Control-Allow-Credentials=true}. - * - *

If undefined, credentials are allowed. - */ - String allowCredentials() default ""; - - /** - * The maximum age (in seconds) of the cache duration for pre-flight responses. - * - *

This property controls the value of the {@code Access-Control-Max-Age} - * header in the pre-flight response. - * - *

Setting this to a reasonable value can reduce the number of pre-flight - * request/response interactions required by the browser. - * A negative value means undefined. - * - *

If undefined, max age is set to {@code 1800} seconds (i.e., 30 minutes). - */ - long maxAge() default -1; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/DeleteMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/DeleteMapping.java deleted file mode 100644 index a1d878498bc719fe709557a259fed42382c986cc..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/DeleteMapping.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/4. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface DeleteMapping { - - /** - * Alias for {@link RequestMapping#value()}. - */ - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path()}. - */ - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params()}. - */ - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers()}. - */ - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes()}. - */ - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces()}. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/FormPart.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/FormPart.java deleted file mode 100644 index 9c32976ba13fccd05358d7e60181d2103f44db2b..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/FormPart.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -/** - * Created by Zhenjie Yan on 2018/9/13. - */ -public @interface FormPart { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the request parameter to bind to. - */ - String name() default ""; - - /** - * Whether the parameter is required. - */ - boolean required() default true; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/GetMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/GetMapping.java deleted file mode 100644 index 441b0baa1e7c9c262727512638178582d1fb4e9e..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/GetMapping.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/4. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface GetMapping { - - /** - * Alias for {@link RequestMapping#value()}. - */ - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path()}. - */ - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params()}. - */ - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers()}. - */ - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes()}. - */ - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces()}. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Interceptor.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Interceptor.java deleted file mode 100644 index 4c3834f216b07edb6896e200e5747510c381ad3a..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Interceptor.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface Interceptor { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PatchMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PatchMapping.java deleted file mode 100644 index ed2fbe50717f062beac41a3117eb3f0ec14d742c..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PatchMapping.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/4. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface PatchMapping { - - /** - * Alias for {@link RequestMapping#value()}. - */ - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path()}. - */ - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params()}. - */ - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers()}. - */ - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes()}. - */ - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces()}. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PathVariable.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PathVariable.java deleted file mode 100644 index ae1930780f48d80cb455d4ccd9ba5aee205998fd..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PathVariable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface PathVariable { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the path variable to bind to. - */ - String name() default ""; - - /** - * Whether the path is required. - * - *

Defaults to {@code true}, leading to an exception being thrown if the path is missing in the request. - * - *

Alternatively, provide a {@link #defaultValue()}, which implicitly sets this flag to {@code false}. - */ - boolean required() default true; - - /** - * The default value to use as a fallback. - * - *

Supplying a default value implicitly sets {@link #required()} to {@code false}. - */ - String defaultValue() default ""; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PostMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PostMapping.java deleted file mode 100644 index 01257d58f3eb1767c0122ed7a20b497a4cb36439..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PostMapping.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/4. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface PostMapping { - - /** - * Alias for {@link RequestMapping#value()}. - */ - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path()}. - */ - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params()}. - */ - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers()}. - */ - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes()}. - */ - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces()}. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PutMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PutMapping.java deleted file mode 100644 index 6bebf6da6e63e16078cc8af88dea92013fdaa43b..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/PutMapping.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/4. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface PutMapping { - - /** - * Alias for {@link RequestMapping#value()}. - */ - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path()}. - */ - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params()}. - */ - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers()}. - */ - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes()}. - */ - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces()}. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/QueryParam.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/QueryParam.java deleted file mode 100644 index fb1d955912c29022fefc684c1975390d563c2eed..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/QueryParam.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/13. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface QueryParam { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the request parameter to bind to. - */ - String name() default ""; - - /** - * Whether the parameter is required. - * - *

Defaults to {@code true}, leading to an exception being thrown if the parameter is missing in the request. - * - *

Alternatively, provide a {@link #defaultValue()}, which implicitly sets this flag to {@code false}. - */ - boolean required() default true; - - /** - * The default value to use as a fallback. - * - *

Supplying a default value implicitly sets {@link #required()} to {@code false}. - */ - String defaultValue() default ""; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestBody.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestBody.java deleted file mode 100644 index 2353ce056638519c0ac4474eda3dbea9f5d2f812..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestBody.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface RequestBody { - - /** - * Whether body content is required. - * - *

Default is {@code true}, leading to an exception thrown in case there is no body content. - */ - boolean required() default true; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestHeader.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestHeader.java deleted file mode 100644 index a02df95c8714ee68800dff0919687463bd2d11f7..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestHeader.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface RequestHeader { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the request header to bind to. - */ - String name() default ""; - - /** - * Whether the header is required. - * - *

Defaults to {@code true}, leading to an exception being thrown if the header is missing in the request. - * - *

Alternatively, provide a {@link #defaultValue()}, which implicitly sets this flag to {@code false}. - */ - boolean required() default true; - - /** - * The default value to use as a fallback. - * - *

Supplying a default value implicitly sets {@link #required()} to {@code false}. - */ - String defaultValue() default ""; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMapping.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMapping.java deleted file mode 100644 index 967ad9dec118f7f51c95ff9da77144dbe7812a7b..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMapping.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target({ElementType.METHOD, ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface RequestMapping { - - /** - * Alias for {@link #path()}. - */ - String[] value() default {}; - - /** - * The primary mapping expressed by this annotation. For example {@code @RequestMapping ("/foo")} is equivalent to - * {@code @RequestMapping (path="/foo")}. - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings inherit this primary mapping, narrowing it for a specific handler method. - */ - String[] path() default {}; - - /** - * The HTTP request methods to map to, narrowing the primary mapping: GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, - * TRACE. - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings inherit this HTTP method restriction (i.e. the type-level restriction gets checked before the - * handler method is even resolved). - */ - RequestMethod[] method() default {}; - - /** - * The parameters of the mapped request, narrowing the primary mapping. - * - *

A sequence of "myParam=myValue" style expressions, with a request only mapped if each such parameter is found - * to have the given value. Expressions can be negated by using the "!=" operator, as in "myParam!=myValue". "myParam" - * style expressions are also supported, with such parameters having to be present in the request (allowed to have any - * value). Finally, "!myParam" style expressions indicate that the specified parameter is not supposed to be present in - * the request. - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings inherit this parameter restriction (i.e. the type-level restriction gets checked before the - * handler method is even resolved). - */ - String[] params() default {}; - - /** - * The headers of the mapped request, narrowing the primary mapping. - * - *

A sequence of "My-Header=myValue" style expressions, with a request only mapped if each such header is found - * to have the given value. Expressions can be negated by using the "!=" operator, as in "My-Header!=myValue". - * "My-Header" style expressions are also supported, with such headers having to be present in the request (allowed to - * have any value). Finally, "!My-Header" style expressions indicate that the specified header is not supposed to - * be present in the request. - * - *

Also supports media type wildcards (*), for headers such as Accept and Content-Type. For instance, - * - *

 @RequestMapping(value = "/something", headers = "content-type=text/*") 
- * - * will match requests with a Content-Type of "text/html", "text/plain", etc. - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings inherit this header restriction (i .e. the type-level restriction gets checked before the - * handler method is even resolved). - */ - String[] headers() default {}; - - /** - * The consumable media types of the mapped request, narrowing the primary mapping. - * - *

The format is a single media type or a sequence of media types, with a request only mapped if the {@code - * Content-Type} matches one of these media types. Examples: - * - *

 consumes = "text/plain" consumes = {"text/plain", "application/*"} 
- * - * Expressions can be negated by using the "!" operator, as in "!text/plain", which matches all requests with a {@code - * Content-Type} other than "text/plain". - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings override this consumes restriction. - */ - String[] consumes() default {}; - - /** - * The producible media types of the mapped request, narrowing the primary mapping. - * - *

The format is a single media type or a sequence of media types, with a request only mapped if the {@code - * Accept} matches one of these media types. Examples: - * - *

 produces = "text/plain" produces = {"text/plain", "application/*"} produces =
-     * "application/json; charset=UTF-8" 
- * - *

It affects the actual content type written, for example to produce a JSON response with UTF-8 encoding, {@code - * "application/json; charset=UTF-8"} should be used. - * - *

Expressions can be negated by using the "!" operator, as in "!text/plain", which matches all requests with a - * {@code Accept} other than "text/plain". - * - *

Supported at the type level as well as at the method level. When used at the type level, all - * method-level mappings override this produces restriction. - */ - String[] produces() default {}; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMethod.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMethod.java deleted file mode 100644 index dee8d42e1418d31b04b8030e2ead7f841dab1c2b..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestMethod.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -public enum RequestMethod { - GET("GET"), - HEAD("HEAD"), - POST("POST"), - PUT("PUT"), - PATCH("PATCH"), - DELETE("DELETE"), - OPTIONS("OPTIONS"), - TRACE("TRACE"); - - private String value; - - RequestMethod(String value) { - this.value = value; - } - - public String value() { - return value; - } - - @Override - public String toString() { - return value; - } -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestParam.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestParam.java deleted file mode 100644 index b4f55ebfd8d9942a0e641a2b5f6fa2954eb014ef..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RequestParam.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.SOURCE) -public @interface RequestParam { - - /** - * Alias for {@link #name()}. - */ - String value() default ""; - - /** - * The name of the request parameter to bind to. - */ - String name() default ""; - - /** - * Whether the parameter is required. - * - *

Defaults to {@code true}, leading to an exception being thrown if the parameter is missing in the request. - * - *

Alternatively, provide a {@link #defaultValue()}, which implicitly sets this flag to {@code false}. - */ - boolean required() default true; - - /** - * The default value to use as a fallback. - * - *

Supplying a default value implicitly sets {@link #required()} to {@code false}. - */ - String defaultValue() default ""; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Resolver.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Resolver.java deleted file mode 100644 index 2a91a118045663d58735f2aef1606db00acceda5..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/Resolver.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface Resolver { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/ResponseBody.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/ResponseBody.java deleted file mode 100644 index 1daf53240388cb5109bfbbbd9ad8bf01d45ada55..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/ResponseBody.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target({ElementType.TYPE, ElementType.METHOD}) -@Retention(RetentionPolicy.SOURCE) -public @interface ResponseBody {} \ No newline at end of file diff --git a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RestController.java b/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RestController.java deleted file mode 100644 index 48daff90352332f4ca6866bf39bd8bb8966933b2..0000000000000000000000000000000000000000 --- a/annotation/src/main/java/com/yanzhenjie/andserver/annotation/RestController.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created by Zhenjie Yan on 2018/6/3. - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.SOURCE) -public @interface RestController { - - /** - * Group name. - */ - String value() default "default"; -} \ No newline at end of file diff --git a/api/.gitignore b/api/.gitignore deleted file mode 100644 index 796b96d1c402326528b4ba3c12ee9d92d0e212e9..0000000000000000000000000000000000000000 --- a/api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/api/build.gradle b/api/build.gradle deleted file mode 100644 index 4f80da35d252c89478ad5ff21b539769a970293e..0000000000000000000000000000000000000000 --- a/api/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -apply plugin: 'com.huawei.ohos.library' -ohos { - compileSdkVersion 5 - defaultConfig { - compatibleSdkVersion 5 - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - api project(':annotation') - api 'com.yanzhenjie.apache:fileupload:1.4' - api 'com.yanzhenjie.apache:httpcore:4.4.13.2' - // implementation 'androidx.annotation:annotation:1.1.0' -} diff --git a/api/src/main/config.json b/api/src/main/config.json deleted file mode 100644 index e271453c136cb6b5056ffd31cd6ba3b9c0c2656e..0000000000000000000000000000000000000000 --- a/api/src/main/config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "app": { - "bundleName": "com.yanzhenjie.andserver", - "vendor": "yanzhenjie", - "version": { - "code": 1, - "name": "1.0.1" - }, - "apiVersion": { - "compatible": 5, - "target": 5, - "releaseType": "Beta1" - } - }, - "deviceConfig": {}, - "module": { - "package": "com.yanzhenjie.andserver", - "deviceType": [ - "phone" - ], - "distro": { - "deliveryWithInstall": true, - "moduleName": "api", - "moduleType": "har" - }, - "reqPermissions": [ - { - "name": "ohos.permission.INTERNET" - } - ] - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/AndServer.java b/api/src/main/java/com/yanzhenjie/andserver/AndServer.java deleted file mode 100644 index 5a1551796bdede1a959726c002cf0ee0016a2dd4..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/AndServer.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.server.ProxyServer; -import com.yanzhenjie.andserver.server.WebServer; -import ohos.agp.render.render3d.BuildConfig; -import ohos.app.Context; - -/** - * Created by Zhenjie Yan on 2018/6/9. - */ -public class AndServer { - - public static final String TAG = "AndServer"; - public static final String INFO = String.format("AndServer/%1$s", BuildConfig.VERSION_CODE); - - - /** - * Create a builder for the web server. - * - * @return {@link Server.Builder}. - */ - public static Server.Builder webServer(Context context) { - return WebServer.newBuilder(context, "default"); - } - - /** - * Create a builder for the web server. - * - * @param group group name. - * - * @return {@link Server.Builder}. - */ - - public static Server.Builder webServer( Context context, - String group) { - return WebServer.newBuilder(context, group); - } - - /** - * Create a builder for the reverse proxy server. - * - * @return {@link Server.ProxyBuilder}. - */ - - public static Server.ProxyBuilder proxyServer() { - return ProxyServer.newBuilder(); - } - - /** - * @deprecated use {@link #webServer(Context)} instead. - */ - - @Deprecated - public static Server.Builder serverBuilder( Context context) { - return webServer(context); - } - - /** - * @deprecated use {@link #webServer(Context, String)} instead. - */ - - @Deprecated - public static Server.Builder serverBuilder( Context context, String group) { - return webServer(context, group); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/ComponentRegister.java b/api/src/main/java/com/yanzhenjie/andserver/ComponentRegister.java deleted file mode 100644 index 435a6eefd860668c82cb1747484bf2f6b89e7b2d..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/ComponentRegister.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan - * - * 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.register.OnRegister; -import com.yanzhenjie.andserver.register.Register; -import ohos.app.Context; -import ohos.global.resource.Entry; -import ohos.global.resource.ResourceManager; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/9/23. - */ -public class ComponentRegister { - - private static final String ANDSERVER_REGISTER_SUFFIX = ".andserver"; - private static final String PROCESSOR_PACKAGE = ".andserver.processor.generator."; - private static final List REGISTER_LIST = new ArrayList<>(); - - static { - REGISTER_LIST.add("AdapterRegister"); - REGISTER_LIST.add("ConfigRegister"); - REGISTER_LIST.add("ConverterRegister"); - REGISTER_LIST.add("InterceptorRegister"); - REGISTER_LIST.add("ResolverRegister"); - } - - private Context mContext; - - public ComponentRegister(Context context) { - this.mContext = context; - } - - public void register(Register register, String group) - throws InstantiationException, IllegalAccessException { - ResourceManager manager = mContext.getResourceManager(); - Entry[] pathList = null; - try { - pathList = manager.getRawFileEntry("").getEntries(); - } catch (IOException e) { - e.printStackTrace(); - } - - if (pathList == null || pathList.length == 0) { - return; - } - - String packageName = "com.yanzhenjie.andserver.hos"; - for (String clazz : REGISTER_LIST) { - String className = String.format("%s%s%s", packageName, PROCESSOR_PACKAGE, clazz); - registerClass(register, group, className); - } - } - - private void registerClass(Register register, String group, String className) - throws InstantiationException, IllegalAccessException { - try { - Class clazz = Class.forName(className); - if (OnRegister.class.isAssignableFrom(clazz)) { - OnRegister load = (OnRegister) clazz.newInstance(); - load.onRegister(mContext, group, register); - } - } catch (ClassNotFoundException ignored) { - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/DispatcherHandler.java b/api/src/main/java/com/yanzhenjie/andserver/DispatcherHandler.java deleted file mode 100644 index b337ad96b66e25bc648166f2536971ee913ce0b3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/DispatcherHandler.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error.NotFoundException; -import com.yanzhenjie.andserver.error.ServerInternalException; -import com.yanzhenjie.andserver.framework.ExceptionResolver; -import com.yanzhenjie.andserver.framework.HandlerInterceptor; -import com.yanzhenjie.andserver.framework.MessageConverter; -import com.yanzhenjie.andserver.framework.ModifiedInterceptor; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.framework.config.Multipart; -import com.yanzhenjie.andserver.framework.handler.HandlerAdapter; -import com.yanzhenjie.andserver.framework.handler.RequestHandler; -import com.yanzhenjie.andserver.framework.view.View; -import com.yanzhenjie.andserver.framework.view.ViewResolver; -import com.yanzhenjie.andserver.http.*; -import com.yanzhenjie.andserver.http.cookie.Cookie; -import com.yanzhenjie.andserver.http.multipart.MultipartRequest; -import com.yanzhenjie.andserver.http.multipart.MultipartResolver; -import com.yanzhenjie.andserver.http.multipart.StandardMultipartResolver; -import com.yanzhenjie.andserver.http.session.Session; -import com.yanzhenjie.andserver.http.session.SessionManager; -import com.yanzhenjie.andserver.http.session.StandardSessionManager; -import com.yanzhenjie.andserver.register.Register; -import com.yanzhenjie.andserver.util.Assert; -import ohos.app.Context; -import ohos.hiviewdfx.HiLog; -import ohos.hiviewdfx.HiLogLabel; -import org.apache.httpcore.protocol.HttpRequestHandler; - -import java.io.File; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/8/8. - */ -public class DispatcherHandler implements HttpRequestHandler, Register { - - private final Context mContext; - - private SessionManager mSessionManager; - private MessageConverter mConverter; - private ViewResolver mViewResolver; - private ExceptionResolver mResolver; - private Multipart mMultipart; - - private List mAdapterList = new LinkedList<>(); - private List mInterceptorList = new LinkedList<>(); - - public DispatcherHandler(Context context) { - this.mContext = context; - this.mSessionManager = new StandardSessionManager(context); - this.mViewResolver = new ViewResolver(); - this.mResolver = new ExceptionResolver.ResolverWrapper(ExceptionResolver.DEFAULT); - this.mInterceptorList.add(new ModifiedInterceptor()); - } - - @Override - public void addAdapter(HandlerAdapter adapter) { - Assert.notNull(adapter, "The adapter cannot be null."); - - if (!mAdapterList.contains(adapter)) { - mAdapterList.add(adapter); - } - } - - @Override - public void addInterceptor( HandlerInterceptor interceptor) { - Assert.notNull(interceptor, "The interceptor cannot be null."); - - if (!mInterceptorList.contains(interceptor)) { - mInterceptorList.add(interceptor); - } - } - - @Override - public void setConverter(MessageConverter converter) { - this.mConverter = converter; - this.mViewResolver = new ViewResolver(converter); - } - - @Override - public void setResolver( ExceptionResolver resolver) { - Assert.notNull(resolver, "The exceptionResolver cannot be null."); - this.mResolver = new ExceptionResolver.ResolverWrapper(resolver); - } - - @Override - public void setMultipart(Multipart multipart) { - this.mMultipart = multipart; - } - - @Override - public void handle(org.apache.httpcore.HttpRequest req, org.apache.httpcore.HttpResponse res, - org.apache.httpcore.protocol.HttpContext con) { - HttpRequest request = new StandardRequest(req, new StandardContext(con), this, mSessionManager); - HttpResponse response = new StandardResponse(res); - handle(request, response); - } - - private void handle(HttpRequest request, HttpResponse response) { - MultipartResolver multipartResolver = new StandardMultipartResolver(); - try { - if (multipartResolver.isMultipart(request)) { - configMultipart(multipartResolver); - request = multipartResolver.resolveMultipart(request); - } - - // Determine adapter for the current request. - HandlerAdapter ha = getHandlerAdapter(request); - if (ha == null) { - throw new NotFoundException(request.getPath()); - } - - // Determine handler for the current request. - RequestHandler handler = ha.getHandler(request); - if (handler == null) { - throw new NotFoundException(request.getPath()); - } - - // Pre processor, e.g. interceptor. - if (preHandle(request, response, handler)) { - return; - } - - // Actually invoke the handler. - request.setAttribute(HttpContext.ANDROID_CONTEXT, mContext); - request.setAttribute(HttpContext.HTTP_MESSAGE_CONVERTER, mConverter); - View view = handler.handle(request, response); - mViewResolver.resolve(view, request, response); - processSession(request, response); - } catch (Throwable err) { - try { - mResolver.onResolve(request, response, err); - } catch (Exception e) { - e = new ServerInternalException(e); - response.setStatus(StatusCode.SC_INTERNAL_SERVER_ERROR); - response.setBody(new StringBody(e.getMessage())); - } - processSession(request, response); - } finally { - if (request instanceof MultipartRequest) { - multipartResolver.cleanupMultipart((MultipartRequest) request); - } - } - } - - private void configMultipart(MultipartResolver multipartResolver) { - if (mMultipart != null) { - long allFileMaxSize = mMultipart.getAllFileMaxSize(); - if (allFileMaxSize == -1 || allFileMaxSize > 0) { - multipartResolver.setAllFileMaxSize(allFileMaxSize); - } - - long fileMaxSize = mMultipart.getFileMaxSize(); - if (fileMaxSize == -1 || fileMaxSize > 0) { - multipartResolver.setFileMaxSize(fileMaxSize); - } - - int maxInMemorySize = mMultipart.getMaxInMemorySize(); - if (maxInMemorySize > 0) { - multipartResolver.setMaxInMemorySize(maxInMemorySize); - } - - File uploadTempDir = mMultipart.getUploadTempDir(); - if (uploadTempDir != null) { - multipartResolver.setUploadTempDir(uploadTempDir); - } - } - } - - /** - * Return the {@link RequestHandler} for this request. - * - * @param request current HTTP request. - * - * @return the {@link RequestHandler}, or {@code null} if no handler could be found. - */ - private HandlerAdapter getHandlerAdapter(HttpRequest request) { - for (HandlerAdapter ha: mAdapterList) { - if (ha.intercept(request)) { - return ha; - } - } - return null; - } - - /** - * Intercept the execution of a handler. - * - * @param request current request. - * @param response current response. - * @param handler the corresponding handler of the current request. - * - * @return true if the interceptor has processed the request and responded. - */ - private boolean preHandle(HttpRequest request, HttpResponse response, RequestHandler handler) throws Exception { - for (HandlerInterceptor interceptor: mInterceptorList) { - if (interceptor.onIntercept(request, response, handler)) { - return true; - } - } - return false; - } - - - public RequestDispatcher getRequestDispatcher(final HttpRequest request, final String path) { - HttpRequest copyRequest = request; - while (copyRequest instanceof RequestWrapper) { - RequestWrapper wrapper = (RequestWrapper) request; - copyRequest = wrapper.getRequest(); - } - - StandardRequest newRequest = (StandardRequest) copyRequest; - newRequest.setPath(path); - - HandlerAdapter ha = getHandlerAdapter(copyRequest); - if (ha == null) { - throw new NotFoundException(request.getPath()); - } - - return new RequestDispatcher() { - @Override - public void forward( HttpRequest request, HttpResponse response) { - handle(request, response); - } - }; - } - - private void processSession(HttpRequest request, HttpResponse response) { - Object objSession = request.getAttribute(HttpContext.REQUEST_CREATED_SESSION); - if (objSession instanceof Session) { - Session session = (Session) objSession; - try { - mSessionManager.add(session); - } catch (IOException e) { - HiLog.error(new HiLogLabel(0,1, AndServer.TAG), "Session persistence failed.", e); - } - - Cookie cookie = new Cookie(HttpRequest.SESSION_NAME, session.getId()); - cookie.setPath("/"); - cookie.setHttpOnly(true); - response.addCookie(cookie); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/ProxyHandler.java b/api/src/main/java/com/yanzhenjie/andserver/ProxyHandler.java deleted file mode 100644 index 4236432ec8ea1df602d2d5ee5389346cf6204a51..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/ProxyHandler.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.error.NotFoundException; -import com.yanzhenjie.andserver.server.ProxyServer; -import com.yanzhenjie.andserver.util.IOUtils; -import org.apache.httpcore.*; -import org.apache.httpcore.entity.StringEntity; -import org.apache.httpcore.impl.DefaultBHttpClientConnection; -import org.apache.httpcore.impl.DefaultConnectionReuseStrategy; -import org.apache.httpcore.protocol.*; - -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.*; - -import static com.yanzhenjie.andserver.server.ProxyServer.PROXY_CONN_CLIENT; - -/** - * Created by Zhenjie Yan on 3/7/20. - */ -public class ProxyHandler implements HttpRequestHandler { - - private static final int BUFFER = 8 * 1024; - - private final static Set HOP_BY_HOP = Collections.unmodifiableSet(new HashSet<>(Arrays.asList( - HttpHeaders.HOST, - HttpHeaders.CONTENT_LENGTH, - HttpHeaders.TRANSFER_ENCODING, - HttpHeaders.CONNECTION, - HttpHeaders.PROXY_AUTHENTICATE, - HttpHeaders.TE, - HttpHeaders.TRAILER, - HttpHeaders.UPGRADE - ))); - - private final Map mHostList; - - private final SSLSocketFactory mSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); - - private final HttpRequestExecutor mHttpExecutor = new HttpRequestExecutor(); - private final HttpProcessor mRequestProcessor = new ImmutableHttpProcessor( - new RequestContent(), - new RequestTargetHost(), - new RequestConnControl(), - new RequestUserAgent(AndServer.INFO), - new RequestExpectContinue(true)); - - public ProxyHandler(Map hostList) { - this.mHostList = hostList; - } - - @Override - public void handle(HttpRequest request, HttpResponse response, HttpContext context) - throws HttpException, IOException { - String hostHeader = request.getFirstHeader(HttpHeaders.HOST).getValue(); - String hostName = HttpHost.create(hostHeader).getHostName(); - HttpHost host = mHostList.get(hostName.toLowerCase(Locale.ROOT)); - if (host == null) { - NotFoundException e = new NotFoundException(request.getRequestLine().getUri()); - response.setStatusCode(e.getStatusCode()); - response.setEntity(new StringEntity(e.getMessage())); - return; - } - - // Remove hop-by-hop headers. - for (String name: HOP_BY_HOP) { - request.removeHeaders(name); - } - - DefaultBHttpClientConnection conn = (DefaultBHttpClientConnection) context.getAttribute(PROXY_CONN_CLIENT); - if (!conn.isOpen() || conn.isStale()) { - Socket socket = createSocket(host); - conn.bind(socket); - } - - context.setAttribute(HttpCoreContext.HTTP_CONNECTION, conn); - context.setAttribute(HttpCoreContext.HTTP_TARGET_HOST, host); - - mHttpExecutor.preProcess(request, mRequestProcessor, context); - HttpResponse outResponse = mHttpExecutor.execute(request, conn, context); - mHttpExecutor.postProcess(response, mRequestProcessor, context); - - // Remove hop-by-hop headers. - for (String name: HOP_BY_HOP) { - outResponse.removeHeaders(name); - } - - response.setStatusLine(outResponse.getStatusLine()); - response.setHeaders(outResponse.getAllHeaders()); - response.setEntity(outResponse.getEntity()); - - boolean keepAlive = DefaultConnectionReuseStrategy.INSTANCE.keepAlive(response, context); - context.setAttribute(ProxyServer.PROXY_CONN_ALIVE, keepAlive); - } - - private Socket createSocket(HttpHost host) throws IOException { - Socket socket = new Socket(); - socket.setSoTimeout(60 * 1000); - socket.setReuseAddress(true); - socket.setTcpNoDelay(true); - socket.setKeepAlive(true); - socket.setReceiveBufferSize(BUFFER); - socket.setSendBufferSize(BUFFER); - socket.setSoLinger(true, 0); - - String scheme = host.getSchemeName(); - String hostName = host.getHostName(); - int port = host.getPort(); - - InetSocketAddress address = resolveAddress(scheme, hostName, port); - socket.connect(address, 10 * 1000); - - if ("https".equalsIgnoreCase(scheme)) { - SSLSocket sslSocket = (SSLSocket) mSocketFactory.createSocket(socket, hostName, port, true); - try { - sslSocket.startHandshake(); - final SSLSession session = sslSocket.getSession(); - if (session == null) { - throw new SSLHandshakeException("SSL session not available."); - } - } catch (final IOException ex) { - IOUtils.closeQuietly(sslSocket); - throw ex; - } - return sslSocket; - } - return socket; - } - - private InetSocketAddress resolveAddress(String scheme, String hostName, int port) { - if (port < 0) { - if ("http".equalsIgnoreCase(scheme)) { - port = 80; - } else if ("https".equalsIgnoreCase(scheme)) { - port = 443; - } - } - return new InetSocketAddress(hostName, port); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/SSLSocketInitializer.java b/api/src/main/java/com/yanzhenjie/andserver/SSLSocketInitializer.java deleted file mode 100644 index 3aea58c697d4a2afa6a1d8cc243196a00869643a..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/SSLSocketInitializer.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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 javax.net.ssl.SSLException; -import javax.net.ssl.SSLServerSocket; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public interface SSLSocketInitializer { - - void onCreated(SSLServerSocket socket) throws SSLException; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/Server.java b/api/src/main/java/com/yanzhenjie/andserver/Server.java deleted file mode 100644 index b5fb156835d178650752b3787656e6b841065dfe..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/Server.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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 javax.net.ServerSocketFactory; -import javax.net.ssl.SSLContext; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.concurrent.TimeUnit; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public interface Server { - - /** - * Server running status. - * - * @return return true, not return false. - */ - boolean isRunning(); - - /** - * Start the server. - */ - void startup(); - - /** - * Quit the server. - */ - void shutdown(); - - /** - * Get the local address of this server socket. - * - * @return {@link InetAddress}. - * - * @throws IllegalStateException if the server is not started, an IllegalStateException is thrown. - * @see ServerSocket#getInetAddress() - */ - InetAddress getInetAddress(); - - /** - * Returns the port number on which this socket is listening. - * - * @return the local port number to which this socket is bound or -1 if the socket is not bound yet. - * - * @throws IllegalStateException if the server is not started, an IllegalStateException is thrown. - * @see Socket#getLocalPort() - */ - int getPort(); - - interface Builder { - - /** - * Specified server need to monitor the ip address. - */ - T inetAddress(InetAddress inetAddress); - - /** - * Specify the port on which the server listens. - */ - T port(int port); - - /** - * Connection and response timeout. - */ - T timeout(int timeout, TimeUnit timeUnit); - - /** - * Assigns {@link ServerSocketFactory} instance. - */ - T serverSocketFactory(ServerSocketFactory factory); - - /** - * Assigns {@link SSLContext} instance. - */ - T sslContext(SSLContext sslContext); - - /** - * Assigns {@link SSLSocketInitializer} instance. - */ - T sslSocketInitializer(SSLSocketInitializer initializer); - - /** - * Set the server listener. - */ - T listener(ServerListener listener); - - /** - * Create a server. - */ - S build(); - } - - interface ProxyBuilder { - - /** - * Add host address to proxy. - * - * @param hostName such as: {@code www.example.com}, {@code api.example.com}, {@code 192.168.1.111}. - * @param proxyHost such as: {@code http://127.0.0.1:8080}, {@code http://localhost:8181} - */ - T addProxy(String hostName, String proxyHost); - - /** - * Specified server need to monitor the ip address. - */ - T inetAddress(InetAddress inetAddress); - - /** - * Specify the port on which the server listens. - */ - T port(int port); - - /** - * Connection and response timeout. - */ - T timeout(int timeout, TimeUnit timeUnit); - - /** - * Assigns {@link ServerSocketFactory} instance. - */ - T serverSocketFactory(ServerSocketFactory factory); - - /** - * Assigns {@link SSLContext} instance. - */ - T sslContext(SSLContext sslContext); - - /** - * Assigns {@link SSLSocketInitializer} instance. - */ - T sslSocketInitializer(SSLSocketInitializer initializer); - - /** - * Set the server listener. - */ - T listener(ServerListener listener); - - /** - * Create a server. - */ - S 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 onException(Exception e); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/BasicException.java b/api/src/main/java/com/yanzhenjie/andserver/error/BasicException.java deleted file mode 100644 index c716c3b70d77e91eb702f381cc271f02f6d6cb56..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/BasicException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.error; - -/** - * Created by Zhenjie Yan on 11/22/20. - * - * @deprecated use {@link HttpException} instead. - */ -@Deprecated -public class BasicException extends HttpException { - - public BasicException(int statusCode, String message) { - super(statusCode, message); - } - - public BasicException(int statusCode, String message, Throwable cause) { - super(statusCode, message, cause); - } - - public BasicException(int statusCode, Throwable cause) { - super(statusCode, cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/BodyMissingException.java b/api/src/main/java/com/yanzhenjie/andserver/error/BodyMissingException.java deleted file mode 100644 index 80f633af53e86525446b026e4b9b246eaf4599ef..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/BodyMissingException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public class BodyMissingException extends HttpException { - - private static final String MESSAGE = "RequestBody is missing."; - - public BodyMissingException() { - super(StatusCode.SC_BAD_REQUEST, MESSAGE); - } - - public BodyMissingException(Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, MESSAGE, cause); - } - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotAcceptableException.java b/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotAcceptableException.java deleted file mode 100644 index 80ac03ba3ffdaa3648060b0fc26e4c4e9f45008f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotAcceptableException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/8. - */ -public class ContentNotAcceptableException extends HttpException { - - private static final String MESSAGE = "Could not find acceptable representation."; - - public ContentNotAcceptableException() { - super(StatusCode.SC_NOT_ACCEPTABLE, MESSAGE); - } - - public ContentNotAcceptableException(String message, Throwable cause) { - super(StatusCode.SC_NOT_ACCEPTABLE, message, cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotSupportedException.java b/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotSupportedException.java deleted file mode 100644 index 504e396cdfd43b0ac45d47aab2e97809d0c5bda7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/ContentNotSupportedException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; -import com.yanzhenjie.andserver.util.MediaType; - -/** - * Created by Zhenjie Yan on 2018/9/8. - */ -public class ContentNotSupportedException extends HttpException { - - private static final String MESSAGE = "The content type [%s] is not supported."; - - public ContentNotSupportedException(MediaType mediaType) { - super(StatusCode.SC_UNSUPPORTED_MEDIA_TYPE, String.format(MESSAGE, mediaType)); - } - - public ContentNotSupportedException(MediaType mediaType, Throwable cause) { - super(StatusCode.SC_UNSUPPORTED_MEDIA_TYPE, String.format(MESSAGE, mediaType), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/CookieMissingException.java b/api/src/main/java/com/yanzhenjie/andserver/error/CookieMissingException.java deleted file mode 100644 index abcf6ac2e2598944e299a83cd7d86898dcad05f0..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/CookieMissingException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class CookieMissingException extends HttpException { - - private static final String MESSAGE = "Missing cookie [%s] for method parameter."; - - public CookieMissingException(String name) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); - } - - public CookieMissingException(String name, Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); - } - - public CookieMissingException(Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/HeaderMissingException.java b/api/src/main/java/com/yanzhenjie/andserver/error/HeaderMissingException.java deleted file mode 100644 index 28eeff8d01bb3f267cf31a6113c841640ac88d32..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/HeaderMissingException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class HeaderMissingException extends HttpException { - - private static final String MESSAGE = "Missing header [%s] for method parameter."; - - public HeaderMissingException(String name) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); - } - - public HeaderMissingException(String name, Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); - } - - public HeaderMissingException(Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/HeaderValidateException.java b/api/src/main/java/com/yanzhenjie/andserver/error/HeaderValidateException.java deleted file mode 100644 index a1cb3b73ed5bc7b7aa17ee46a76476873c737148..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/HeaderValidateException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class HeaderValidateException extends HttpException { - - public HeaderValidateException(String message) { - super(StatusCode.SC_FORBIDDEN, message); - } - - public HeaderValidateException(String message, Throwable cause) { - super(StatusCode.SC_FORBIDDEN, message, cause); - } - - public HeaderValidateException(Throwable cause) { - super(StatusCode.SC_FORBIDDEN, cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/HttpException.java b/api/src/main/java/com/yanzhenjie/andserver/error/HttpException.java deleted file mode 100644 index 8ab17be8e9e9d6c0d5502cec2ea729851e0bbe38..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/HttpException.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -/** - * Created by Zhenjie Yan on 2018/7/19. - */ -public class HttpException extends RuntimeException { - - /** - * Status code. - */ - private int mStatusCode; - - public HttpException(int statusCode, String message) { - super(message); - this.mStatusCode = statusCode; - } - - public HttpException(int statusCode, String message, Throwable cause) { - super(message, cause); - this.mStatusCode = statusCode; - } - - public HttpException(int statusCode, Throwable cause) { - super(cause); - this.mStatusCode = statusCode; - } - - public int getStatusCode() { - return mStatusCode; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMediaTypeException.java b/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMediaTypeException.java deleted file mode 100644 index 28a37a0d31aa49348d2af4dfa8f2074e11208661..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMediaTypeException.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -/** - * Created by Zhenjie Yan on 2018/7/10. - */ -public class InvalidMediaTypeException extends IllegalArgumentException { - - private String mMediaType; - - /** - * Create a new InvalidMediaTypeException for the given media type. - * - * @param mediaType the offending media type. - * @param message a detail message indicating the invalid part. - */ - public InvalidMediaTypeException(String mediaType, String message) { - super("Invalid media type \"" + mediaType + "\": " + message); - this.mMediaType = mediaType; - } - - /** - * Constructor that allows wrapping {@link InvalidMimeTypeException}. - */ - public InvalidMediaTypeException(InvalidMimeTypeException ex) { - super(ex.getMessage(), ex); - this.mMediaType = ex.getMimeType(); - } - - /** - * Return the offending media type. - */ - public String getMediaType() { - return this.mMediaType; - } - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMimeTypeException.java b/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMimeTypeException.java deleted file mode 100644 index 86dc4f52ef657392364de9b855aeb12926ff4cdc..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/InvalidMimeTypeException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -/** - * Created by Zhenjie Yan on 2018/7/10. - */ -public class InvalidMimeTypeException extends IllegalArgumentException { - - private final String mMimeType; - - /** - * Create a new InvalidContentTypeException for the given content type. - * - * @param mimeType the offending media type. - * @param message a detail message indicating the invalid part. - */ - public InvalidMimeTypeException(String mimeType, String message) { - super("Invalid mime type \"" + mimeType + "\": " + message); - this.mMimeType = mimeType; - } - - /** - * Return the offending content type. - */ - public String getMimeType() { - return this.mMimeType; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/MaxUploadSizeExceededException.java b/api/src/main/java/com/yanzhenjie/andserver/error/MaxUploadSizeExceededException.java deleted file mode 100644 index beda78dfdb0cdfc106dd9020e9e5adef85510b1f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/MaxUploadSizeExceededException.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public class MaxUploadSizeExceededException extends HttpException { - - private final long mMaxSize; - - /** - * Constructor for MaxUploadSizeExceededException. - * - * @param maxUploadSize the maximum upload size allowed. - */ - public MaxUploadSizeExceededException(long maxUploadSize) { - this(maxUploadSize, null); - } - - /** - * Constructor for MaxUploadSizeExceededException. - * - * @param maxSize the maximum upload size allowed. - * @param ex root cause from multipart parsing API in use. - */ - public MaxUploadSizeExceededException(long maxSize, Throwable ex) { - super(StatusCode.SC_REQUEST_ENTITY_TOO_LARGE, "Maximum upload size of " + maxSize + " bytes exceeded", ex); - this.mMaxSize = maxSize; - } - - /** - * Return the maximum upload size allowed. - */ - public long getMaxSize() { - return this.mMaxSize; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/MethodNotSupportException.java b/api/src/main/java/com/yanzhenjie/andserver/error/MethodNotSupportException.java deleted file mode 100644 index 392670c1685257c51a8393100ada054841160548..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/MethodNotSupportException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - - -import com.yanzhenjie.andserver.http.HttpMethod; -import com.yanzhenjie.andserver.http.StatusCode; - -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/7/19. - */ -public class MethodNotSupportException extends HttpException { - - private static final String MESSAGE = "The request method [%s] is not supported."; - - private List mMethods; - - public MethodNotSupportException(HttpMethod method) { - super(StatusCode.SC_METHOD_NOT_ALLOWED, String.format(MESSAGE, method.value())); - } - - public MethodNotSupportException(HttpMethod method, Throwable cause) { - super(StatusCode.SC_METHOD_NOT_ALLOWED, String.format(MESSAGE, method.value()), cause); - } - - public List getMethods() { - return mMethods; - } - - public void setMethods(List methods) { - mMethods = methods; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/MultipartException.java b/api/src/main/java/com/yanzhenjie/andserver/error/MultipartException.java deleted file mode 100644 index cf6bcb18eb542d8470dede7b1824ed313ad24216..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/MultipartException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public class MultipartException extends HttpException { - - /** - * Constructor for MultipartException. - * - * @param msg the detail message. - */ - public MultipartException(String msg) { - super(StatusCode.SC_BAD_REQUEST, msg); - } - - /** - * Constructor for MultipartException. - * - * @param msg the detail message - * @param cause the root cause from the multipart parsing API in use - */ - public MultipartException(String msg, Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, msg, cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/NotFoundException.java b/api/src/main/java/com/yanzhenjie/andserver/error/NotFoundException.java deleted file mode 100644 index 3c6de0d960b55ffbcfe53facfa892e6b5ea9e8a8..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/NotFoundException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/7/19. - */ -public class NotFoundException extends HttpException { - - private static final String MESSAGE = "The resource [%s] is not found."; - - public NotFoundException() { - super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, "")); - } - - public NotFoundException(String path) { - super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, path)); - } - - public NotFoundException(String path, Throwable cause) { - super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, path), cause); - } - - public NotFoundException(Throwable cause) { - super(StatusCode.SC_NOT_FOUND, String.format(MESSAGE, ""), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/ParamMissingException.java b/api/src/main/java/com/yanzhenjie/andserver/error/ParamMissingException.java deleted file mode 100644 index 5dad959d833c95cf087ff0da6dda805b6225aef5..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/ParamMissingException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class ParamMissingException extends HttpException { - - private static final String MESSAGE = "Missing param [%s] for method parameter."; - - public ParamMissingException(String name) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); - } - - public ParamMissingException(String name, Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); - } - - public ParamMissingException(Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/ParamValidateException.java b/api/src/main/java/com/yanzhenjie/andserver/error/ParamValidateException.java deleted file mode 100644 index 2f8246fff4750cf29e59250adf2c128e1b80ae7b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/ParamValidateException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/8. - */ -public class ParamValidateException extends HttpException { - - public ParamValidateException(String message) { - super(StatusCode.SC_FORBIDDEN, message); - } - - public ParamValidateException(String message, Throwable cause) { - super(StatusCode.SC_FORBIDDEN, message, cause); - } - - public ParamValidateException(Throwable cause) { - super(StatusCode.SC_FORBIDDEN, cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/PathMissingException.java b/api/src/main/java/com/yanzhenjie/andserver/error/PathMissingException.java deleted file mode 100644 index c0405a81924d6e454f182121c80560d0c80c3244..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/PathMissingException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public class PathMissingException extends HttpException { - - private static final String MESSAGE = "Missing param [%s] for path parameter."; - - public PathMissingException(String name) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name)); - } - - public PathMissingException(String name, Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, name), cause); - } - - public PathMissingException(Throwable cause) { - super(StatusCode.SC_BAD_REQUEST, String.format(MESSAGE, ""), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/error/ServerInternalException.java b/api/src/main/java/com/yanzhenjie/andserver/error/ServerInternalException.java deleted file mode 100644 index 058004b30d01b9f21646856cf8a679a9ba83a56d..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/error/ServerInternalException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.error; - -import com.yanzhenjie.andserver.http.StatusCode; - -/** - * Created by Zhenjie Yan on 2018/9/4. - */ -public class ServerInternalException extends HttpException { - - private static final String MESSAGE = "Server internal error"; - - public ServerInternalException(String subMessage) { - super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s, %s.", MESSAGE, subMessage)); - } - - public ServerInternalException(String subMessage, Throwable cause) { - super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s, %s.", MESSAGE, subMessage), cause); - } - - public ServerInternalException(Throwable cause) { - super(StatusCode.SC_INTERNAL_SERVER_ERROR, String.format("%s.", MESSAGE), cause); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/ETag.java b/api/src/main/java/com/yanzhenjie/andserver/framework/ETag.java deleted file mode 100644 index 74491a37c199cdc60e00e2a41a1a070856122eaf..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/ETag.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework; - - -import com.yanzhenjie.andserver.http.HttpRequest; - -/** - * Created by Zhenjie Yan on 2018/8/31. - */ -public interface ETag { - - /** - * Get the {@code ETag} requesting the specified resource. - * - *

Can simply return {@code null} if there's no support. - */ - String getETag(HttpRequest request) throws Throwable; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/ExceptionResolver.java b/api/src/main/java/com/yanzhenjie/andserver/framework/ExceptionResolver.java deleted file mode 100644 index e59e2a99d53fbe6f376da078264fd110545e0468..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/ExceptionResolver.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework; - - -import com.yanzhenjie.andserver.error.HttpException; -import com.yanzhenjie.andserver.error.MethodNotSupportException; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.http.*; -import com.yanzhenjie.andserver.util.TextUtils; - -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/8/8. - */ -public interface ExceptionResolver { - - class ResolverWrapper implements ExceptionResolver { - - private final ExceptionResolver mResolver; - - public ResolverWrapper(ExceptionResolver resolver) { - this.mResolver = resolver; - } - - @Override - public void onResolve(HttpRequest request, HttpResponse response, Throwable e) { - if (e instanceof MethodNotSupportException) { - List methods = ((MethodNotSupportException) e).getMethods(); - if (methods != null && methods.size() > 0) { - response.setHeader(HttpHeaders.ALLOW, TextUtils.join(", ", methods)); - } - } - mResolver.onResolve(request, response, e); - } - } - - ExceptionResolver DEFAULT = new ExceptionResolver() { - @Override - public void onResolve( HttpRequest request, HttpResponse response, Throwable e) { - if (e instanceof HttpException) { - HttpException ex = (HttpException) e; - response.setStatus(ex.getStatusCode()); - } else { - response.setStatus(StatusCode.SC_INTERNAL_SERVER_ERROR); - } - response.setBody(new StringBody(e.getMessage())); - } - }; - - /** - * Resolve exceptions that occur in the program, replacing the default output information for the exception. - * - * @param request current request. - * @param response current response. - * @param e an exception occurred in the program. - */ - void onResolve(HttpRequest request, HttpResponse response, Throwable e); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/HandlerInterceptor.java b/api/src/main/java/com/yanzhenjie/andserver/framework/HandlerInterceptor.java deleted file mode 100644 index ed8aff069b6584ba3b91751597582a7a8d510f44..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/HandlerInterceptor.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework; - - -import com.yanzhenjie.andserver.framework.handler.RequestHandler; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; - -/** - * Created by Zhenjie Yan on 2018/8/8. - */ -public interface HandlerInterceptor { - - /** - * Intercept the execution of a handler. - * - * @param request current request. - * @param response current response. - * @param handler the corresponding handler of the current request. - * - * @return true if the interceptor has processed the request and responded. - */ - boolean onIntercept(HttpRequest request, HttpResponse response, RequestHandler handler) - throws Exception; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/LastModified.java b/api/src/main/java/com/yanzhenjie/andserver/framework/LastModified.java deleted file mode 100644 index 7a6c366524a886d694218adc9e6c7bcd10ddebae..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/LastModified.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework; - -import com.yanzhenjie.andserver.http.HttpRequest; - -/** - * Created by Zhenjie Yan on 2018/8/29. - */ -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 request - * - * @return the time the underlying resource was last modified, or -1 meaning that the content must always be - * regenerated. - */ - long getLastModified(HttpRequest request) throws Throwable; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/MessageConverter.java b/api/src/main/java/com/yanzhenjie/andserver/framework/MessageConverter.java deleted file mode 100644 index 3c5637722da1073e7bedfc2450e021ff8f28bc95..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/MessageConverter.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework; - - - -import com.yanzhenjie.andserver.framework.view.ViewResolver; -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.MediaType; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Type; - -/** - * Created by Zhenjie Yan on 2018/9/6. - */ -public interface MessageConverter { - - /** - * Convert a specific output to the response body. Some of the return values of handlers that cannot be recognized - * by - * {@link ViewResolver} require a message converter to be converted to a response body. - * - * @param output output of handle. - * @param mediaType the content media type specified by the handler. - */ - ResponseBody convert(Object output, MediaType mediaType); - - /** - * Convert RequestBody to a object. - * - * @param stream {@link InputStream}. - * @param mediaType he content media type. - * @param type type of object. - * @param type of object. - * - * @return object. - */ - - T convert(InputStream stream, MediaType mediaType, Type type) throws IOException; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/ModifiedInterceptor.java b/api/src/main/java/com/yanzhenjie/andserver/framework/ModifiedInterceptor.java deleted file mode 100644 index d98e54448174f3b25a219b20d7229eef56c8c031..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/ModifiedInterceptor.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework; - - -import com.yanzhenjie.andserver.AndServer; -import com.yanzhenjie.andserver.framework.handler.RequestHandler; -import com.yanzhenjie.andserver.http.HttpMethod; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.http.Modified; -import ohos.hiviewdfx.HiLog; -import ohos.hiviewdfx.HiLogLabel; - -/** - * Created by Zhenjie Yan on 2018/9/14. - */ -public class ModifiedInterceptor implements HandlerInterceptor { - - @Override - public boolean onIntercept(HttpRequest request, HttpResponse response, - RequestHandler handler) { - // Process cache header, if supported by the handler. - HttpMethod method = request.getMethod(); - if (method == HttpMethod.GET || method == HttpMethod.HEAD) { - String eTag = null; - try { - eTag = handler.getETag(request); - } catch (Throwable e) { - HiLog.warn(new HiLogLabel(0, 1, AndServer.TAG),"", e); - } - long lastModified = -1; - try { - lastModified = handler.getLastModified(request); - } catch (Throwable e) { - HiLog.warn(new HiLogLabel(0, 1, AndServer.TAG),"", e); - } - return new Modified(request, response).process(eTag, lastModified); - } - return false; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/body/FileBody.java b/api/src/main/java/com/yanzhenjie/andserver/framework/body/FileBody.java deleted file mode 100644 index 3272edb7edff41c29e8ef3188e3c46a1c364cc1b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/body/FileBody.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.body; - -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.IOUtils; -import com.yanzhenjie.andserver.util.MediaType; - -import java.io.*; - -/** - * Created by Zhenjie Yan on 2018/8/6. - */ -public class FileBody implements ResponseBody { - - private File mBody; - - public FileBody(File body) { - if (body == null) { - throw new IllegalArgumentException("The file cannot be null."); - } - this.mBody = body; - } - - @Override - public boolean isRepeatable() { - return true; - } - - @Override - public long contentLength() { - return mBody.length(); - } - - - @Override - public MediaType contentType() { - return MediaType.getFileMediaType(mBody.getName()); - } - - @Override - public void writeTo(OutputStream output) throws IOException { - InputStream is = new FileInputStream(mBody); - IOUtils.write(is, output); - IOUtils.closeQuietly(is); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/body/JsonBody.java b/api/src/main/java/com/yanzhenjie/andserver/framework/body/JsonBody.java deleted file mode 100644 index 756f06aac5d475f75fec7b34bdb8df95575bb186..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/body/JsonBody.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.body; - - -import com.yanzhenjie.andserver.util.MediaType; -import ohos.utils.zson.ZSONObject; - -/** - * Created by Zhenjie Yan on 2018/8/8. - */ -public class JsonBody extends StringBody { - - public JsonBody(String body) { - super(body); - } - - public JsonBody(ZSONObject object) { - super(object.toString()); - } - - @Override - public MediaType contentType() { - return MediaType.APPLICATION_JSON_UTF8; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/body/StreamBody.java b/api/src/main/java/com/yanzhenjie/andserver/framework/body/StreamBody.java deleted file mode 100644 index a64a4739986b39bbf5633f68545aeb93b2c36d91..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/body/StreamBody.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.body; - - - - -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.IOUtils; -import com.yanzhenjie.andserver.util.MediaType; - -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public class StreamBody implements ResponseBody { - - private InputStream mStream; - private long mLength; - private MediaType mMediaType; - - public StreamBody(InputStream stream) { - this(stream, MediaType.APPLICATION_OCTET_STREAM); - } - - public StreamBody(InputStream stream, long length) { - this(stream, length, MediaType.APPLICATION_OCTET_STREAM); - } - - public StreamBody(InputStream stream, MediaType mediaType) { - this(stream, 0, mediaType); - } - - public StreamBody(InputStream stream, long length, MediaType mediaType) { - this.mStream = stream; - this.mLength = length; - this.mMediaType = mediaType; - } - - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public long contentLength() { - if (mLength == 0 && mStream instanceof FileInputStream) { - try { - mLength = ((FileInputStream) mStream).getChannel().size(); - return mLength; - } catch (IOException e) { - e.printStackTrace(); - } - } - return mLength; - } - - - @Override - public MediaType contentType() { - return mMediaType; - } - - @Override - public void writeTo(OutputStream output) throws IOException { - IOUtils.write(mStream, output); - IOUtils.closeQuietly(mStream); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/body/StringBody.java b/api/src/main/java/com/yanzhenjie/andserver/framework/body/StringBody.java deleted file mode 100644 index 95dda0a44f68dc88588788c1a639bc2f97775dec..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/body/StringBody.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.body; - -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.IOUtils; -import com.yanzhenjie.andserver.util.MediaType; -import org.apache.commons.io.Charsets; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -/** - * Created by Zhenjie Yan on 2018/8/6. - */ -public class StringBody implements ResponseBody { - - private byte[] mBody; - private MediaType mMediaType; - - public StringBody(String body) { - this(body, MediaType.TEXT_PLAIN); - } - - public StringBody(String body, MediaType mediaType) { - if (body == null) { - throw new IllegalArgumentException("The content cannot be null."); - } - - this.mMediaType = mediaType; - if (mMediaType == null) { - mMediaType = new MediaType(MediaType.TEXT_PLAIN, StandardCharsets.UTF_8); - } - - Charset charset = mMediaType.getCharset(); - if (charset == null) { - charset = StandardCharsets.UTF_8; - } - this.mBody = body.getBytes(charset); - } - - @Override - public boolean isRepeatable() { - return true; - } - - @Override - public long contentLength() { - return mBody.length; - } - - - @Override - public MediaType contentType() { - Charset charset = mMediaType.getCharset(); - if (charset == null) { - charset = StandardCharsets.UTF_8; - return new MediaType(mMediaType.getType(), mMediaType.getSubtype(), charset); - } - return mMediaType; - } - - @Override - public void writeTo(OutputStream output) throws IOException { - IOUtils.write(output, mBody); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/config/Delegate.java b/api/src/main/java/com/yanzhenjie/andserver/framework/config/Delegate.java deleted file mode 100644 index 7f4c837f138237f2d6da6dd3364a73481c622759..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/config/Delegate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright © 2019 Zhenjie Yan. - * - * 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.framework.config; - - -import com.yanzhenjie.andserver.framework.website.Website; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2019-06-30. - */ -public class Delegate implements WebConfig.Delegate { - - public static Delegate newInstance() { - return new Delegate(); - } - - private Multipart mMultipart; - private List mWebsites; - - private Delegate() { - mWebsites = new ArrayList<>(); - } - - public Multipart getMultipart() { - return mMultipart; - } - - @Override - public void setMultipart(Multipart multipart) { - mMultipart = multipart; - } - - public List getWebsites() { - return mWebsites; - } - - @Override - public void addWebsite(Website website) { - mWebsites.add(website); - } -} diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/config/Multipart.java b/api/src/main/java/com/yanzhenjie/andserver/framework/config/Multipart.java deleted file mode 100644 index fed0090ec1e1df67660248bc80ab05a63e839942..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/config/Multipart.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright © 2019 Zhenjie Yan. - * - * 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.framework.config; - -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; - -import java.io.File; - -/** - * Created by Zhenjie Yan on 2019-06-28. - */ -public class Multipart { - - public static Builder newBuilder() { - return new Builder(); - } - - private final long allFileMaxSize; - private final long fileMaxSize; - private final int maxInMemorySize; - private final File uploadTempDir; - - private Multipart(Builder builder) { - this.allFileMaxSize = builder.allFileMaxSize; - this.fileMaxSize = builder.fileMaxSize; - this.maxInMemorySize = builder.maxInMemorySize; - this.uploadTempDir = builder.uploadTempDir; - } - - public long getAllFileMaxSize() { - return allFileMaxSize; - } - - public long getFileMaxSize() { - return fileMaxSize; - } - - public int getMaxInMemorySize() { - return maxInMemorySize; - } - - public File getUploadTempDir() { - return uploadTempDir; - } - - public static class Builder { - - private long allFileMaxSize; - private long fileMaxSize; - private int maxInMemorySize; - private File uploadTempDir; - - private Builder() { - } - - /** - * Set the maximum size (in bytes) allowed for uploading. -1 indicates no limit (the default). - * - * @param allFileMaxSize the maximum upload size allowed. - * - * @see FileUpload#setSizeMax(long) - */ - public Builder allFileMaxSize(long allFileMaxSize) { - this.allFileMaxSize = allFileMaxSize; - return this; - } - - /** - * Set the maximum size (in bytes) allowed for each individual file. -1 indicates no limit (the default). - * - * @param fileMaxSize the maximum upload size per file. - * - * @see FileUpload#setFileSizeMax(long) - */ - public Builder fileMaxSize(long fileMaxSize) { - this.fileMaxSize = fileMaxSize; - return this; - } - - /** - * Set the maximum allowed size (in bytes) before uploads are written to disk, default is 10240. - * - * @param maxInMemorySize the maximum in memory size allowed. - * - * @see DiskFileItemFactory#setSizeThreshold(int) - */ - public Builder maxInMemorySize(int maxInMemorySize) { - this.maxInMemorySize = maxInMemorySize; - return this; - } - - /** - * Set the temporary directory where uploaded files get stored. - */ - public Builder uploadTempDir(File uploadTempDir) { - this.uploadTempDir = uploadTempDir; - return this; - } - - public Multipart build() { - return new Multipart(this); - } - - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/config/WebConfig.java b/api/src/main/java/com/yanzhenjie/andserver/framework/config/WebConfig.java deleted file mode 100644 index fb1a92bb09eca8dad9d2139ae86f7fef18d9a190..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/config/WebConfig.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2019 Zhenjie Yan. - * - * 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.framework.config; - -import com.yanzhenjie.andserver.framework.website.Website; -import ohos.app.Context; - -/** - * Created by Zhenjie Yan on 2019-06-28. - *

- * @Config
- * public class AppConfig implements WebConfig {
- *
- *     @Override
- *     public void onConfig(Context context, Delegate delegate) {
- *         Website website = ...;
- *         delegate.addWebsite(website);
- *
- *         Multipart multipart = Multipart.newBuilder()...build();
- *         delegate.setMultipart(multipart);
- *     }
- * }
- * 
- */ -public interface WebConfig { - - void onConfig(Context context, Delegate delegate); - - interface Delegate { - - /** - * - */ - void setMultipart(Multipart multipart); - - /** - * - */ - void addWebsite(Website website); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/cross/CrossOrigin.java b/api/src/main/java/com/yanzhenjie/andserver/framework/cross/CrossOrigin.java deleted file mode 100644 index 69209b264aa3a3c49d0633e2a96b6af437d0269e..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/cross/CrossOrigin.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.framework.cross; - - -import com.yanzhenjie.andserver.http.HttpMethod; - -/** - * Created by Zhenjie Yan on 10/16/20. - */ -public class CrossOrigin { - - private String[] origins; - private String[] allowedHeaders; - private String[] exposedHeaders; - private HttpMethod[] methods; - private boolean allowCredentials; - private long maxAge; - - public CrossOrigin() { - } - - - public String[] getOrigins() { - return origins; - } - - public void setOrigins(String[] origins) { - this.origins = origins; - } - - - public String[] getAllowedHeaders() { - return allowedHeaders; - } - - public void setAllowedHeaders(String[] allowedHeaders) { - this.allowedHeaders = allowedHeaders; - } - - - public String[] getExposedHeaders() { - return exposedHeaders; - } - - public void setExposedHeaders(String[] exposedHeaders) { - this.exposedHeaders = exposedHeaders; - } - - - public HttpMethod[] getMethods() { - return methods; - } - - public void setMethods(HttpMethod[] methods) { - this.methods = methods; - } - - - public boolean isAllowCredentials() { - return allowCredentials; - } - - public void setAllowCredentials(boolean allowCredentials) { - this.allowCredentials = allowCredentials; - } - - - public long getMaxAge() { - return maxAge; - } - - public void setMaxAge(long maxAge) { - this.maxAge = maxAge; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/HandlerAdapter.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/HandlerAdapter.java deleted file mode 100644 index 301566dda44fe3eb8fe8c059b9cc93935860df42..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/HandlerAdapter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.handler; - - -import com.yanzhenjie.andserver.http.HttpRequest; - -/** - * Created by Zhenjie Yan on 2018/9/4. - */ -public interface HandlerAdapter { - - /** - * Whether to intercept the current request. - * - * @param request current request. - * - * @return returns true, otherwise false. - */ - boolean intercept(HttpRequest request); - - /** - * Get the handler that handles the current request. - * - * @param request current request. - * - * @return the handler to handle current request. - * - * @throws if current request cannot find the corresponding handler. - */ - RequestHandler getHandler(HttpRequest request); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingAdapter.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingAdapter.java deleted file mode 100644 index 9d57f6ea01e9e04aa8cd3673c50f6b00c3562a0e..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingAdapter.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.handler; - - -import com.yanzhenjie.andserver.error.*; -import com.yanzhenjie.andserver.framework.mapping.Mapping; -import com.yanzhenjie.andserver.framework.mapping.Mime; -import com.yanzhenjie.andserver.framework.mapping.Pair; -import com.yanzhenjie.andserver.framework.mapping.Path; -import com.yanzhenjie.andserver.http.HttpContext; -import com.yanzhenjie.andserver.http.HttpMethod; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.util.MediaType; -import com.yanzhenjie.andserver.util.Patterns; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/9/8. - */ -public abstract class MappingAdapter implements HandlerAdapter, Patterns { - - @Override - public boolean intercept(HttpRequest request) { - List pathSegments = Path.pathToList(request.getPath()); - - List mappings = getExactMappings(pathSegments); - if (mappings.isEmpty()) { - mappings = getBlurredMappings(pathSegments); - } - if (mappings.isEmpty()) { - return false; - } - - HttpMethod method = request.getMethod(); - if (method.equals(HttpMethod.OPTIONS)) { - return true; - } - - Mapping mapping = MappingAdapter.findMappingByMethod(mappings, method); - if (mapping == null) { - MethodNotSupportException exception = new MethodNotSupportException(method); - List methods = MappingAdapter.findSupportMethods(mappings); - exception.setMethods(methods); - throw exception; - } - - Pair param = mapping.getParam(); - if (param != null) { - validateParams(param, request); - } - - Pair header = mapping.getHeader(); - if (header != null) { - validateHeaders(header, request); - } - - Mime consume = mapping.getConsume(); - if (consume != null) { - validateConsume(consume, request); - } - - Mime produce = mapping.getProduce(); - if (produce != null) { - validateProduce(produce, request); - } - - return true; - } - - - @Override - public RequestHandler getHandler( HttpRequest request) { - List pathSegments = Path.pathToList(request.getPath()); - - List mappings = getExactMappings(pathSegments); - if (mappings.isEmpty()) { - mappings = getBlurredMappings(pathSegments); - } - - HttpMethod method = request.getMethod(); - Mapping mapping = MappingAdapter.findMappingByMethod(mappings, method); - - if (method.equals(HttpMethod.OPTIONS) && mapping == null) { - return new OptionsHandler(request, mappings, getMappingMap()); - } - - if (mapping == null) { - return null; - } - - Mime mime = mapping.getProduce(); - if (mime != null) { - List produces = mime.getRuleList(); - MediaType mediaType = null; - for (Mime.Rule produce: produces) { - String text = produce.toString(); - if (!text.startsWith("!")) { - mediaType = produce; - break; - } - } - request.setAttribute(HttpContext.RESPONSE_PRODUCE_TYPE, mediaType); - } - - return getMappingMap().get(mapping); - } - - private List getExactMappings(List httpSegments) { - List mappings = new ArrayList<>(); - - Map mappingMap = getMappingMap(); - for (Mapping mapping: mappingMap.keySet()) { - Path path = mapping.getPath(); - List rules = path.getRuleList(); - for (Path.Rule rule: rules) { - if (matchExactPath(rule.getSegments(), httpSegments)) { - mappings.add(mapping); - } - } - } - return mappings; - } - - private boolean matchExactPath(List segments, List httpSegments) { - if (httpSegments.size() != segments.size()) { - return false; - } - - if (Path.listToPath(segments).equals(Path.listToPath(httpSegments))) { - return true; - } - return false; - } - - private List getBlurredMappings(List httpSegments) { - List mappings = new ArrayList<>(); - - Map mappingMap = getMappingMap(); - for (Mapping mapping: mappingMap.keySet()) { - Path path = mapping.getPath(); - List rules = path.getRuleList(); - for (Path.Rule rule: rules) { - if (matchBlurredPath(rule.getSegments(), httpSegments)) { - mappings.add(mapping); - } - } - } - return mappings; - } - - private boolean matchBlurredPath(List segments, List httpSegments) { - if (httpSegments.size() != segments.size()) { - return false; - } - - for (int i = 0; i < segments.size(); i++) { - Path.Segment segment = segments.get(i); - if (!segment.equals(httpSegments.get(i)) && !segment.isBlurred()) { - return false; - } - } - return true; - } - - private void validateParams(Pair param, HttpRequest request) { - List rules = param.getRuleList(); - for (Pair.Rule rule: rules) { - String key = rule.getKey(); - List keys = request.getParameterNames(); - String value = rule.getValue(); - List values = request.getParameters(key); - if (rule.isNoKey()) { - if (keys.contains(key)) { - throw new ParamValidateException(String.format("The parameter [%s] is not allowed.", key)); - } - } else if (rule.isNoValue()) { - if (values.contains(value)) { - throw new ParamValidateException( - String.format("The value of parameter %s cannot be %s.", key, value)); - } - } else if (!key.isEmpty() && !value.isEmpty()) { - if (!keys.contains(key) || !values.contains(value)) { - throw new ParamValidateException( - String.format("The value of parameter %s is missing or wrong.", key)); - } - } else if (!key.isEmpty() && value.isEmpty()) { - if (!keys.contains(key)) { - throw new ParamValidateException(String.format("The parameter %s is missing.", key)); - } - } - } - } - - private void validateHeaders(Pair header, HttpRequest request) { - List rules = header.getRuleList(); - for (Pair.Rule rule: rules) { - String key = rule.getKey(); - List keys = request.getHeaderNames(); - String value = rule.getValue(); - List values = request.getHeaders(key); - if (rule.isNoKey()) { - if (keys.contains(key)) { - throw new HeaderValidateException(String.format("The header [%s] is not allowed.", key)); - } - } else if (rule.isNoValue()) { - if (values.contains(value)) { - throw new HeaderValidateException( - String.format("The value of header %s cannot be %s.", key, value)); - } - } else if (!key.isEmpty() && !value.isEmpty() && - (!keys.contains(key) || !values.contains(value))) { - throw new HeaderValidateException(String.format("The value of header %s is missing or wrong.", key)); - } else if (!key.isEmpty() && value.isEmpty()) { - if (!keys.contains(key)) { - throw new HeaderValidateException(String.format("The header %s is missing.", key)); - } - } - } - } - - private void validateConsume(Mime mime, HttpRequest request) { - List rules = mime.getRuleList(); - MediaType contentType = request.getContentType(); - - List includeType = new ArrayList<>(); - for (Mime.Rule rule: rules) { - String type = rule.getType(); - boolean nonContent = type.startsWith("!"); - if (nonContent) { - type = type.substring(1); - } - MediaType consume = new MediaType(type, rule.getSubtype()); - - if (nonContent) { - if (consume.equalsExcludeParameter(contentType)) { - throw new ContentNotSupportedException(contentType); - } - } else { - includeType.add(consume); - } - } - - boolean included = false; - for (MediaType mediaType: includeType) { - if (mediaType.includes(contentType)) { - included = true; - break; - } - } - if (!included) { - throw new ContentNotSupportedException(contentType); - } - } - - private void validateProduce(Mime mime, HttpRequest request) { - List rules = mime.getRuleList(); - List accepts = request.getAccepts(); - for (Mime.Rule rule: rules) { - String type = rule.getType(); - boolean nonContent = type.startsWith("!"); - if (nonContent) { - type = type.substring(1); - } - MediaType produce = new MediaType(type, rule.getSubtype()); - - boolean exclude = false; - for (MediaType accept: accepts) { - if (accept.includes(produce)) { - exclude = true; - } - } - if (nonContent && exclude) { - throw new ContentNotAcceptableException(); - } - if (!nonContent && !exclude) { - throw new ContentNotAcceptableException(); - } - } - } - - /** - * Get all the mappings for this adapter. - * - * @return all mappings, non-null, non-empty. - */ - - protected abstract Map getMappingMap(); - - /** - * Get the host of the {@code HandlerAdapter}. - * - * @return the host of the adapter. - */ - - protected abstract Object getHost(); - - public static List findSupportMethods(List mappings) { - List methods = new ArrayList<>(); - for (Mapping child: mappings) { - methods.addAll(child.getMethod().getRuleList()); - } - return methods; - } - - public static Mapping findMappingByMethod(List mappings, HttpMethod method) { - for (Mapping child: mappings) { - if (child.getMethod().getRuleList().contains(method)) { - return child; - } - } - return null; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingHandler.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingHandler.java deleted file mode 100644 index bd344f0a1abea964deb23d6260cae5bfc92b854e..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MappingHandler.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.handler; - -import com.yanzhenjie.andserver.framework.ETag; -import com.yanzhenjie.andserver.framework.LastModified; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.framework.cross.CrossOrigin; -import com.yanzhenjie.andserver.framework.mapping.Addition; -import com.yanzhenjie.andserver.framework.mapping.Mapping; -import com.yanzhenjie.andserver.framework.mapping.Path; -import com.yanzhenjie.andserver.framework.view.BodyView; -import com.yanzhenjie.andserver.framework.view.View; -import com.yanzhenjie.andserver.http.HttpHeaders; -import com.yanzhenjie.andserver.http.HttpMethod; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.util.StringUtils; -import com.yanzhenjie.andserver.util.TextUtils; -import org.apache.httpcore.HttpStatus; - -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public abstract class MappingHandler implements MethodHandler { - - private final Object mHost; - private final Mapping mMapping; - private final Addition mAddition; - private final CrossOrigin mCrossOrigin; - - public MappingHandler(Object host, Mapping mapping, Addition addition, - CrossOrigin crossOrigin) { - this.mHost = host; - this.mMapping = mapping; - this.mAddition = addition; - this.mCrossOrigin = crossOrigin; - } - - @Override - public String getETag( HttpRequest request) throws Throwable { - Object o = getHost(); - if (o instanceof ETag) { - return ((ETag) o).getETag(request); - } - return null; - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - Object o = getHost(); - if (o instanceof LastModified) { - return ((LastModified) o).getLastModified(request); - } - return -1; - } - - - @Override - public Addition getAddition() { - return mAddition; - } - - - @Override - public CrossOrigin getCrossOrigin() { - return mCrossOrigin; - } - - - @Override - public Mapping getMapping() { - return mMapping; - } - - - protected Object getHost() { - return mHost; - } - - /** - * Get the path to match the request. - * - * @param httpPath http path. - * - * @return the path of handler. - */ - - protected Map getPathVariable( String httpPath) { - List httpSegments = Path.pathToList(httpPath); - List ruleList = mMapping.getPath().getRuleList(); - for (Path.Rule rule: ruleList) { - List segments = rule.getSegments(); - if (httpSegments.size() != segments.size()) { - continue; - } - - String path = Path.listToPath(segments); - if (path.equals(httpPath)) { - return Collections.emptyMap(); - } - - boolean matches = true; - boolean isBlurred = false; - for (int i = 0; i < segments.size(); i++) { - Path.Segment segment = segments.get(i); - boolean blurred = segment.isBlurred(); - isBlurred = isBlurred || blurred; - if (!segment.equals(httpSegments.get(i)) && !blurred) { - matches = false; - break; - } - } - - if (matches && isBlurred) { - Map map = new HashMap<>(); - for (int i = 0; i < segments.size(); i++) { - Path.Segment segment = segments.get(i); - if (segment.isBlurred()) { - Path.Segment httpSegment = httpSegments.get(i); - - String key = segment.getValue(); - key = key.substring(1, key.length() - 1); - map.put(key, httpSegment.getValue()); - } - } - return map; - } - } - - return Collections.emptyMap(); - } - - @Override - public View handle(HttpRequest request, HttpResponse response) throws Throwable { - String origin = request.getHeader(HttpHeaders.ORIGIN); - if (!StringUtils.isEmpty(origin) && mCrossOrigin != null) { - HttpMethod method = request.getMethod(); - - List allowMethods = Arrays.asList(mCrossOrigin.getMethods()); - if (!allowMethods.isEmpty() && !allowMethods.contains(method)) { - return invalidCORS(response); - } - - response.setHeader(HttpHeaders.Access_Control_Allow_Origin, origin); - boolean credentials = mCrossOrigin.isAllowCredentials(); - response.setHeader(HttpHeaders.Access_Control_Allow_Credentials, Boolean.toString(credentials)); - response.setHeader(HttpHeaders.VARY, HttpHeaders.ORIGIN); - } - - return onHandle(request, response); - } - - private View invalidCORS(HttpResponse response, HttpMethod... methods) { - response.setStatus(HttpStatus.SC_FORBIDDEN); - if (methods != null && methods.length > 0) { - response.setHeader(HttpHeaders.ALLOW, TextUtils.join(", ", methods)); - } - return new BodyView(new StringBody(OptionsHandler.INVALID_CORS_REQUEST)); - } - - protected abstract View onHandle(HttpRequest request, HttpResponse response) throws Throwable; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MethodHandler.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MethodHandler.java deleted file mode 100644 index 49317b9537934234cebd87beec5001daa944dc33..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/MethodHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.handler; - - -import com.yanzhenjie.andserver.framework.cross.CrossOrigin; -import com.yanzhenjie.andserver.framework.mapping.Addition; -import com.yanzhenjie.andserver.framework.mapping.Mapping; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public interface MethodHandler extends RequestHandler { - - /** - * Get addition configuration, addition provides some added value. - * - * @return {@link Addition}. - */ - - Addition getAddition(); - - /** - * Get cross origin information. - * - * @return {@link CrossOrigin} - */ - - CrossOrigin getCrossOrigin(); - - /** - * Get mapping configuration, mapping provides all the annotation information for this method. - * - * @return {@link Mapping}. - */ - - Mapping getMapping(); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/OptionsHandler.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/OptionsHandler.java deleted file mode 100644 index bb551407e7876ac53db0f48bfbbc35ece08f2167..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/OptionsHandler.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.framework.handler; - -import com.yanzhenjie.andserver.error.NotFoundException; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.framework.cross.CrossOrigin; -import com.yanzhenjie.andserver.framework.mapping.Addition; -import com.yanzhenjie.andserver.framework.mapping.Mapping; -import com.yanzhenjie.andserver.framework.view.BodyView; -import com.yanzhenjie.andserver.framework.view.View; -import com.yanzhenjie.andserver.http.HttpHeaders; -import com.yanzhenjie.andserver.http.HttpMethod; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.util.TextUtils; -import org.apache.httpcore.HttpStatus; - -import java.util.*; - -/** - * Created by Zhenjie Yan on 10/17/20. - */ -public class OptionsHandler implements MethodHandler { - - public static final String INVALID_CORS_REQUEST = "Invalid CORS request."; - - private List mMappings; - private Map mMappingMap; - - private Mapping mMapping; - private MethodHandler mHandler; - - public OptionsHandler(HttpRequest optionsRequest, List mappings, Map mappingMap) { - this.mMappings = mappings; - this.mMappingMap = mappingMap; - - mMapping = mMappings.get(0); - String requestMethod = optionsRequest.getHeader(HttpHeaders.Access_Control_Request_Method); - if (!requestMethod.isEmpty()) { - HttpMethod method = HttpMethod.reverse(requestMethod); - Mapping exactMapping = MappingAdapter.findMappingByMethod(mMappings, method); - if (exactMapping != null) { - mMapping = exactMapping; - } - } - - mHandler = (MethodHandler) mMappingMap.get(mMapping); - } - - - @Override - public Addition getAddition() { - return mHandler.getAddition(); - } - - - @Override - public CrossOrigin getCrossOrigin() { - return mHandler.getCrossOrigin(); - } - - - @Override - public Mapping getMapping() { - return mMapping; - } - - @Override - public View handle( HttpRequest request, HttpResponse response) throws Throwable { - String requestOrigin = request.getHeader(HttpHeaders.ORIGIN); - if (requestOrigin.isEmpty()) { - return invalidCORS(response); - } - - String requestMethodText = request.getHeader(HttpHeaders.Access_Control_Request_Method); - if (requestMethodText.isEmpty()) { - return invalidCORS(response); - } - - HttpMethod requestMethod = HttpMethod.reverse(requestMethodText); - Mapping mapping = MappingAdapter.findMappingByMethod(mMappings, requestMethod); - if (mapping == null) { - return invalidCORS(response); - } - - MethodHandler handler = (MethodHandler) mMappingMap.get(mapping); - if (handler == null) { - throw new NotFoundException(); - } - - CrossOrigin crossOrigin = handler.getCrossOrigin(); - if (crossOrigin == null) { - return invalidCORS(response); - } - - List allowMethods = new ArrayList<>(); - Collections.addAll(allowMethods, crossOrigin.getMethods()); - List mappingMethods = mapping.getMethod().getRuleList(); - if (allowMethods.isEmpty()) { - allowMethods.addAll(mappingMethods); - } - if (!allowMethods.contains(requestMethod)) { - return invalidCORS(response); - } - - List allowOrigins = Arrays.asList(crossOrigin.getOrigins()); - if (!allowOrigins.isEmpty() && !allowOrigins.contains("*") && !allowOrigins.contains(requestOrigin)) { - return invalidCORS(response); - } - - List allowedHeaders = Arrays.asList(crossOrigin.getAllowedHeaders()); - List outHeaders = new ArrayList<>(); - String headerHeadersText = request.getHeader(HttpHeaders.Access_Control_Request_Headers); - List requestHeaders = new ArrayList<>(); - if (!headerHeadersText.isEmpty()) { - StringTokenizer st = new StringTokenizer(headerHeadersText, ","); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - token = token.trim(); - if (token.length() > 0) { - requestHeaders.add(token); - } - } - } - if (allowedHeaders.contains("*")) { - if (requestHeaders.size() > 0) { - outHeaders.addAll(requestHeaders); - } - } else if (allowedHeaders.size() > 0) { - if (requestHeaders.size() > 0) { - for (String allowedHeader: allowedHeaders) { - for (String requestHeader: requestHeaders) { - if (allowedHeader.equalsIgnoreCase(requestHeader)) { - outHeaders.add(requestHeader); - } - } - } - if (outHeaders.isEmpty()) { - return invalidCORS(response); - } - } - } else if (requestHeaders.size() > 0) { - outHeaders.addAll(requestHeaders); - } - - String[] exposeHeaders = crossOrigin.getExposedHeaders(); - - response.setHeader(HttpHeaders.Access_Control_Allow_Origin, requestOrigin); - response.setHeader(HttpHeaders.Access_Control_Allow_Methods, TextUtils.join(", ", allowMethods)); - if (outHeaders.size() > 0) { - response.setHeader(HttpHeaders.Access_Control_Allow_Headers, TextUtils.join(", ", outHeaders)); - } - if (exposeHeaders.length > 0) { - response.setHeader(HttpHeaders.Access_Control_Expose_Headers, String.join(", ", exposeHeaders)); - } - - boolean credentials = crossOrigin.isAllowCredentials(); - response.setHeader(HttpHeaders.Access_Control_Allow_Credentials, Boolean.toString(credentials)); - - long maxAge = crossOrigin.getMaxAge(); - response.setHeader(HttpHeaders.Access_Control_Max_Age, Long.toString(maxAge)); - - response.setHeader(HttpHeaders.ALLOW, TextUtils.join(", ", HttpMethod.values())); - response.setHeader(HttpHeaders.VARY, HttpHeaders.ORIGIN); - - return new BodyView(new StringBody("OK")); - } - - private View invalidCORS(HttpResponse response) { - response.setStatus(HttpStatus.SC_FORBIDDEN); - response.setHeader(HttpHeaders.ALLOW, TextUtils.join(", ", HttpMethod.values())); - return new BodyView(new StringBody(INVALID_CORS_REQUEST)); - } - - @Override - public String getETag( HttpRequest request) throws Throwable { - return mHandler.getETag(request); - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - return mHandler.getLastModified(request); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/RequestHandler.java b/api/src/main/java/com/yanzhenjie/andserver/framework/handler/RequestHandler.java deleted file mode 100644 index ead5ddce5aca8c53a49eefee9ebc12c461bb93b3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/handler/RequestHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.handler; - - -import com.yanzhenjie.andserver.framework.ETag; -import com.yanzhenjie.andserver.framework.LastModified; -import com.yanzhenjie.andserver.framework.view.View; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; - -/** - * Created by Zhenjie Yan on 2018/8/28. - */ -public interface RequestHandler extends ETag, LastModified { - - /** - * Use the given handler to handle this request. - * - * @param request current request. - * @param response current response. - * - * @return the impression sent to the client. - */ - View handle(HttpRequest request, HttpResponse response) throws Throwable; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Addition.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Addition.java deleted file mode 100644 index 750c37be09c4204c753d4082c2545b6f9a38c883..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Addition.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - - - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class Addition { - - private String[] stringType; - private boolean[] booleanType; - private int[] intType; - private long[] longType; - private short[] shortType; - private float[] floatType; - private double[] doubleType; - private byte[] byteType; - private char[] charType; - - public Addition() { - } - - - public String[] getStringType() { - return stringType; - } - - public void setStringType(String[] stringType) { - this.stringType = stringType; - } - - - public boolean[] getBooleanType() { - return booleanType; - } - - public void setBooleanType(boolean[] booleanType) { - this.booleanType = booleanType; - } - - - public int[] getIntType() { - return intType; - } - - public void setIntType(int[] intType) { - this.intType = intType; - } - - - public long[] getLongType() { - return longType; - } - - public void setLongType(long[] longType) { - this.longType = longType; - } - - - public short[] getShortType() { - return shortType; - } - - public void setShortType(short[] shortType) { - this.shortType = shortType; - } - - - public float[] getFloatType() { - return floatType; - } - - public void setFloatType(float[] floatType) { - this.floatType = floatType; - } - - - public double[] getDoubleType() { - return doubleType; - } - - public void setDoubleType(double[] doubleType) { - this.doubleType = doubleType; - } - - - public byte[] getByteType() { - return byteType; - } - - public void setByteType(byte[] byteType) { - this.byteType = byteType; - } - - - public char[] getCharType() { - return charType; - } - - public void setCharType(char[] charType) { - this.charType = charType; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mapping.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mapping.java deleted file mode 100644 index ca70981cfc2d807e6b5d78fead12165253b2ad33..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mapping.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - -/** - *

Save the request mapping configuration.

- * - * Created by Zhenjie Yan on 2018/6/13. - */ -public class Mapping { - - private Path mPath; - private Method mMethod; - private Pair mParam; - private Pair mHeader; - private Mime mConsume; - private Mime mProduce; - - public Mapping() { - } - - public Path getPath() { - return mPath; - } - - public void setPath(Path path) { - mPath = path; - } - - public Method getMethod() { - return mMethod; - } - - public void setMethod(Method method) { - mMethod = method; - } - - public Pair getParam() { - return mParam; - } - - public void setParam(Pair param) { - mParam = param; - } - - public Pair getHeader() { - return mHeader; - } - - public void setHeader(Pair header) { - mHeader = header; - } - - public Mime getConsume() { - return mConsume; - } - - public void setConsume(Mime consume) { - mConsume = consume; - } - - public Mime getProduce() { - return mProduce; - } - - public void setProduce(Mime produce) { - mProduce = produce; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Method.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Method.java deleted file mode 100644 index 3c4f2daf15a9b620827e331c6ca8c782c73c1da7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Method.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - -import com.yanzhenjie.andserver.http.HttpMethod; - -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/6/14. - */ -public class Method { - - private List mRuleList = new LinkedList<>(); - - public Method() { - } - - - public List getRuleList() { - return mRuleList; - } - - public void addRule( String ruleText) { - mRuleList.add(HttpMethod.reverse(ruleText)); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mime.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mime.java deleted file mode 100644 index 8fd067bf4aecc931ce0048eb475e7dbf50e8dace..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Mime.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - - -import com.yanzhenjie.andserver.util.MediaType; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/6/14. - */ -public class Mime { - - private List mRuleList = new LinkedList<>(); - - public Mime() { - } - - - public List getRuleList() { - return mRuleList; - } - - public void addRule( String ruleText) { - MediaType mimeType = MediaType.valueOf(ruleText); - Rule rule = new Rule(mimeType.getType(), mimeType.getSubtype(), mimeType.getParameters()); - mRuleList.add(rule); - } - - public static class Rule extends MediaType { - - public Rule(String type, String subtype, Map parameters) { - super(type, subtype, parameters); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Pair.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Pair.java deleted file mode 100644 index 717acbe71db14f2166f4f7ace6269412c06052e2..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Pair.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - - -import com.yanzhenjie.andserver.util.Patterns; - -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/6/14. - */ -public class Pair implements Patterns { - - private List mRuleList = new LinkedList<>(); - - public Pair() { - } - - - public List getRuleList() { - return mRuleList; - } - - public void addRule( String ruleText) { - if (ruleText.matches(PAIR_NO_VALUE)) { - String[] keyValue = ruleText.split("="); - Rule rule = new Rule(); - String key = keyValue[0]; - rule.setKey(key.substring(0, key.length() - 1)); - rule.setValue(keyValue[1]); - rule.setNoValue(true); - mRuleList.add(rule); - } else if (ruleText.matches(PAIR_KEY_VALUE)) { - String[] keyValue = ruleText.split("="); - - Rule rule = new Rule(); - rule.setKey(keyValue[0]); - rule.setValue(keyValue[1]); - mRuleList.add(rule); - } else if (ruleText.matches(PAIR_NO_KEY)) { - Rule rule = new Rule(); - rule.setKey(ruleText.substring(1)); - rule.setNoKey(true); - mRuleList.add(rule); - } else if (ruleText.matches(PAIR_KEY)) { - Rule rule = new Rule(); - rule.setKey(ruleText); - mRuleList.add(rule); - } - } - - public static class Rule { - - private String key; - private String value; - private boolean noKey; - private boolean noValue; - - public Rule() { - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public boolean isNoKey() { - return noKey; - } - - public void setNoKey(boolean noKey) { - this.noKey = noKey; - } - - public boolean isNoValue() { - return noValue; - } - - public void setNoValue(boolean noValue) { - this.noValue = noValue; - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Path.java b/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Path.java deleted file mode 100644 index bfa78e36a34ecfcfe9a29470d786d5a920d6c24b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/mapping/Path.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.mapping; - - -import com.yanzhenjie.andserver.util.Patterns; - -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/6/14. - */ -public class Path implements Patterns { - - private List mRuleList = new LinkedList<>(); - - public Path() { - } - - - public List getRuleList() { - return mRuleList; - } - - public void addRule( String ruleText) { - Rule rule = new Rule(); - rule.setSegments(pathToList(ruleText)); - mRuleList.add(rule); - } - - public static class Rule { - - private List mSegments; - - public Rule() { - } - - public List getSegments() { - return mSegments; - } - - public void setSegments(List segments) { - mSegments = segments; - } - } - - public static class Segment { - - private final String value; - private final boolean isBlurred; - - public Segment(String value, boolean isBlurred) { - this.value = value; - this.isBlurred = isBlurred; - } - - public String getValue() { - return value; - } - - public boolean isBlurred() { - return isBlurred; - } - - @Override - public int hashCode() { - return value.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if(obj == null ){ - return false; - } - if(this == obj){ - return true ; - } - if (!(obj instanceof Segment)) { - return false; - } - return value.equals(((Segment) obj).value); - } - - @Override - public String toString() { - return value; - } - } - - - public static List pathToList( String path) { - List segmentList = new LinkedList<>(); - if (!path.isEmpty()) { - while (path.startsWith("/")) - path = path.substring(1); - while (path.endsWith("/")) - path = path.substring(0, path.length() - 1); - String[] pathArray = path.split("/"); - for (String segmentText: pathArray) { - Segment segment = new Segment(segmentText, segmentText.contains("{")); - segmentList.add(segment); - } - } - return Collections.unmodifiableList(segmentList); - } - - - public static String listToPath( List segments) { - StringBuilder builder = new StringBuilder(""); - if (segments.isEmpty()) { - builder.append("/"); - } - for (Segment segment: segments) { - builder.append("/").append(segment.getValue()); - } - return builder.toString(); - } - - public static boolean matches( String path1, String path2) { - if (path1.equals(path2)) { - return true; - } - - List segments1 = pathToList(path1); - List segments2 = pathToList(path2); - - if (segments1.size() != segments2.size()) { - return false; - } - - boolean matches = true; - for (int i = 0; i < segments1.size(); i++) { - Segment segment = segments1.get(i); - if (!segment.equals(segments2.get(i)) && !segment.isBlurred()) { - matches = false; - break; - } - } - return matches; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/view/BodyView.java b/api/src/main/java/com/yanzhenjie/andserver/framework/view/BodyView.java deleted file mode 100644 index 21b109a0f6d81730439867190db1cff84cf66282..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/view/BodyView.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.view; - - -import com.yanzhenjie.andserver.http.ResponseBody; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public class BodyView implements View { - - private ResponseBody mBody; - - public BodyView( ResponseBody body) { - this.mBody = body; - } - - @Override - public boolean rest() { - return true; - } - - - @Override - public Object output() { - return mBody; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/view/ObjectView.java b/api/src/main/java/com/yanzhenjie/andserver/framework/view/ObjectView.java deleted file mode 100644 index e122d8ebd17eeb97e54c3d42d11e2b261daa9908..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/view/ObjectView.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.framework.view; - - - -/** - * Created by Zhenjie Yan on 2018/9/9. - */ -public class ObjectView implements View { - - private final boolean isRest; - private final Object output; - - public ObjectView(boolean isRest, Object output) { - this.isRest = isRest; - this.output = output; - } - - @Override - public boolean rest() { - return isRest; - } - - - @Override - public Object output() { - return output; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/view/View.java b/api/src/main/java/com/yanzhenjie/andserver/framework/view/View.java deleted file mode 100644 index 8cae4af6db571604d311bc673969fa5086c985d6..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/view/View.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.view; - - - -/** - * Created by Zhenjie Yan on 2018/8/29. - */ -public interface View { - - /** - * Is it a rest style view? - * - * @return true, otherwise is false. - */ - boolean rest(); - - /** - * Get the output. - * - * @return output, e.g. {@code "redirect:/user/list"}, {@code "forward:/user/list"}, {@code "/user/list"}, String, - * JSONObject, Object, Basic data type(int, short, long, double, float, byte, boolean char). - */ - - Object output(); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/view/ViewResolver.java b/api/src/main/java/com/yanzhenjie/andserver/framework/view/ViewResolver.java deleted file mode 100644 index c673d78b8ed944d0aff7fe75c38425fa586d72eb..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/view/ViewResolver.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.view; - - -import com.yanzhenjie.andserver.error.NotFoundException; -import com.yanzhenjie.andserver.error.ServerInternalException; -import com.yanzhenjie.andserver.framework.MessageConverter; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.http.*; -import com.yanzhenjie.andserver.util.MediaType; -import com.yanzhenjie.andserver.util.Patterns; - -/** - * Created by Zhenjie Yan on 2018/8/31. - */ -public class ViewResolver implements Patterns, StatusCode, HttpHeaders { - - private MessageConverter mConverter; - - public ViewResolver() { - } - - public ViewResolver(MessageConverter converter) { - this.mConverter = converter; - } - - /** - * Solve the view and convert the view to http package content. - * - * @param view current view. - * @param request current request. - * @param response current response. - */ - public void resolve(View view, HttpRequest request, HttpResponse response) { - if (view == null) { - return; - } - - Object output = view.output(); - - if (view.rest()) { - resolveRest(output, request, response); - } else { - resolvePath(output, request, response); - } - } - - private void resolveRest(Object output, HttpRequest request, HttpResponse response) { - if (output instanceof ResponseBody) { - response.setBody((ResponseBody) output); - } else if (mConverter != null) { - response.setBody(mConverter.convert(output, obtainProduce(request))); - } else if (output == null) { - response.setBody(new StringBody("")); - } else if (output instanceof String) { - response.setBody(new StringBody(output.toString(), obtainProduce(request))); - } else { - response.setBody(new StringBody(output.toString())); - } - } - - - private MediaType obtainProduce(HttpRequest request) { - final Object mtAttribute = request.getAttribute(HttpContext.RESPONSE_PRODUCE_TYPE); - if (mtAttribute instanceof MediaType) { - return (MediaType) mtAttribute; - } - return null; - } - - private void resolvePath(Object output, HttpRequest request, HttpResponse response) { - if (output instanceof CharSequence) { - final String action = output.toString(); - if (action.isEmpty()) { - return; - } - - // "redirect:(.)*" - if (action.matches(REDIRECT)) { - response.setStatus(SC_FOUND); - if (action.length() >= 9) { - final String path = action.substring(9); - response.setHeader(LOCATION, path); - } - } - // "forward:(.)*" - else if (action.matches(FORWARD)) { - final String path = action.substring(8); - RequestDispatcher dispatcher = request.getRequestDispatcher(path); - if (dispatcher != null) { - dispatcher.forward(request, response); - } else { - throw new NotFoundException(path); - } - } - // "/user/kevin" - else if (action.matches(PATH)) { - final String path = action + ".html"; - RequestDispatcher dispatcher = request.getRequestDispatcher(path); - if (dispatcher != null) { - dispatcher.forward(request, response); - } else { - throw new NotFoundException(path); - } - } else { - throw new NotFoundException(action); - } - } else { - throw new ServerInternalException(String.format("The return value of [%s] is not supported", output)); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/website/AssetsWebsite.java b/api/src/main/java/com/yanzhenjie/andserver/framework/website/AssetsWebsite.java deleted file mode 100644 index 9121a2456901d4b13df939793392808d6d17ff43..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/website/AssetsWebsite.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.website; - -import com.yanzhenjie.andserver.error.NotFoundException; -import com.yanzhenjie.andserver.framework.body.StreamBody; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.*; -import ohos.app.Context; -import ohos.bundle.BundleInfo; -import ohos.bundle.IBundleManager; -import ohos.global.resource.Entry; -import ohos.global.resource.ResourceManager; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public class AssetsWebsite extends BasicWebsite implements Patterns { - - private final AssetsReader mAssetsReader; - private final String mRootPath; - private final BundleInfo mPackageInfo; - - /** - * Create a website object. - * - * @param rootPath website root directory. - */ - public AssetsWebsite( Context context, String rootPath) { - this(context, rootPath, DEFAULT_INDEX); - } - - /** - * Create a website object. - * - * @param rootPath website root directory. - * @param indexFileName the default file name for each directory, e.g. index.html. - */ - public AssetsWebsite( Context context, String rootPath, String indexFileName) { - super(indexFileName); - Assert.isTrue(!rootPath.isEmpty(), "The rootPath cannot be empty."); - Assert.isTrue(!indexFileName.isEmpty(), "The indexFileName cannot be empty."); - - if (!rootPath.matches(PATH)) { - String message = "The format of [%s] is wrong, it should be like [/root/project] or [/root/project/]."; - String format = String.format(message, rootPath); - throw new IllegalArgumentException(format); - } - - this.mAssetsReader = new AssetsReader(context.getResourceManager()); - this.mRootPath = trimSlash(rootPath); - - IBundleManager packageManager = context.getBundleManager(); - try { - mPackageInfo = packageManager.getBundleInfo(context.getBundleName(), 0); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean intercept(HttpRequest request) { - String httpPath = request.getPath(); - InputStream stream = findPathSteam(httpPath); - IOUtils.closeQuietly(stream); - return stream != null; - } - - @Override - public String getETag(HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - InputStream stream = findPathSteam(httpPath); - if (stream != null) { - try { - return DigestUtils.md5DigestAsHex(stream); - } finally { - IOUtils.closeQuietly(stream); - } - } - return null; - } - - @Override - public long getLastModified(HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - InputStream stream = findPathSteam(httpPath); - IOUtils.closeQuietly(stream); - return stream != null ? mPackageInfo.getUpdateTime() : -1; - } - - - @Override - public ResponseBody getBody(HttpRequest request, HttpResponse response) throws IOException { - String httpPath = request.getPath(); - String objectPath = mRootPath + httpPath; - InputStream stream = mAssetsReader.getInputStream(objectPath); - if (stream != null) { - MediaType mediaType = MediaType.getFileMediaType(objectPath); - return new StreamBody(stream, stream.available(), mediaType); - } - - String indexPath = addEndSlash(objectPath) + getIndexFileName(); - InputStream indexStream = mAssetsReader.getInputStream(indexPath); - if (indexStream != null) { - if (!httpPath.endsWith(File.separator)) { - IOUtils.closeQuietly(indexStream); - String redirectPath = addEndSlash(httpPath); - String query = queryString(request); - response.sendRedirect(redirectPath + "?" + query); - return new StringBody(""); - } - - final MediaType mediaType = MediaType.getFileMediaType(indexPath); - return new StreamBody(indexStream, indexStream.available(), mediaType); - } - throw new NotFoundException(httpPath); - - } - - private InputStream findPathSteam(String httpPath) { - String targetPath = mRootPath + httpPath; - InputStream targetStream = mAssetsReader.getInputStream(targetPath); - if (targetStream != null) { - return targetStream; - } - - String indexPath = addEndSlash(targetPath) + getIndexFileName(); - InputStream indexStream = mAssetsReader.getInputStream(indexPath); - if (indexStream != null) { - return indexStream; - } - - return null; - } - - public static class AssetsReader { - - /** - * {@link ResourceManager}. - */ - private ResourceManager mAssetManager; - - /** - * Create {@link AssetsReader}. - * - * @param manager {@link ResourceManager}. - */ - public AssetsReader( ResourceManager manager) { - this.mAssetManager = manager; - } - - /** - * Get stream file. - * - * @param filePath assets in the absolute path. - * - * @return {@link InputStream} or null. - */ - - public InputStream getInputStream( String filePath) { - try { - return mAssetManager.getRawFileEntry(filePath).openRawFile(); - } 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) { - InputStream stream = null; - try { - stream = getInputStream(fileName); - return stream != null; - } finally { - IOUtils.closeQuietly(stream); - } - } - - /** - * 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 List list( String path) { - List fileList = new ArrayList<>(); - try { - Entry[] entries = mAssetManager.getRawFileEntry(path).getEntries(); - if(entries.length > 0){ - String[] files = new String[entries.length]; - for(int i = 0;i < entries.length;i++){ - files[i] = entries[i].getPath(); - } - Collections.addAll(fileList, files); - } - } catch (Throwable ignored) { - } - return fileList; - } - - /** - * Scan all files in the inPath. - * - * @param path path in the path. - * - * @return under inPath absolute path. - */ - - public List scanFile( String path) { - Assert.isTrue(!path.isEmpty(), "The path cannot be empty."); - - List pathList = new ArrayList<>(); - if (isFile(path)) { - pathList.add(path); - } else { - List files = list(path); - for (String file: files) { - String realPath = path + File.separator + file; - if (isFile(realPath)) { - pathList.add(realPath); - } else { - List childList = scanFile(realPath); - if (childList.size() > 0) { - pathList.addAll(childList); - } - } - } - } - return pathList; - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/website/BasicWebsite.java b/api/src/main/java/com/yanzhenjie/andserver/framework/website/BasicWebsite.java deleted file mode 100644 index 90fb6a31b08649cc6098da104cd3463998b01262..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/website/BasicWebsite.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.website; - - - - -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.util.Assert; -import com.yanzhenjie.andserver.util.MultiValueMap; - -import java.io.File; -import java.util.List; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/9/6. - */ -public abstract class BasicWebsite extends Website { - - public static final String DEFAULT_INDEX = "index.html"; - - private final String mIndexFileName; - - public BasicWebsite() { - this(DEFAULT_INDEX); - } - - /** - * Create a website object. - * - * @param indexFileName the default file name for each directory, e.g. index.html. - */ - public BasicWebsite( String indexFileName) { - Assert.isTrue(!indexFileName.isEmpty(), "The indexFileName cannot be empty."); - this.mIndexFileName = indexFileName; - } - - @Override - public String getETag( HttpRequest request) throws Throwable { - return null; - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - return -1; - } - - /** - * Get the name of the indexFile. - * - * @return file name, does not include the path. - */ - - protected final String getIndexFileName() { - return mIndexFileName; - } - - /** - * Add the '/' to 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; - } - - /** - * Add '/' at the ending. - * - * @param target target string. - * - * @return rule result. - */ - protected String addEndSlash( String target) { - if (!target.endsWith(File.separator)) { - target = target + File.separator; - } - return target; - } - - /** - * Remove '/' 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 '/' at the ending. - * - * @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 ending. - * - * @param target target string. - * - * @return rule result. - */ - protected String trimSlash( String target) { - target = trimStartSlash(target); - target = trimEndSlash(target); - return target; - } - - protected String queryString(HttpRequest request) { - MultiValueMap query = request.getQuery(); - if (query.isEmpty()) { - return ""; - } - - StringBuilder queryString = new StringBuilder(); - for (Map.Entry> entry: query.entrySet()) { - String key = entry.getKey(); - List values = entry.getValue(); - if (values != null && !values.isEmpty()) { - for (int i = 0; i < values.size(); i++) { - queryString.append("&") - .append(key) - .append("=") - .append(values.get(i)); - } - } - } - if (queryString.length() > 0) { - queryString.deleteCharAt(0); - } - return queryString.toString(); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/website/FileBrowser.java b/api/src/main/java/com/yanzhenjie/andserver/framework/website/FileBrowser.java deleted file mode 100644 index 2457546e42506e3f2bc322d8b91bdf09bfd7a4b4..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/website/FileBrowser.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.website; - - -import com.yanzhenjie.andserver.error.NotFoundException; -import com.yanzhenjie.andserver.framework.body.FileBody; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.*; -import org.apache.commons.io.Charsets; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public class FileBrowser extends BasicWebsite implements Patterns { - - 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 = "
"; - - private final String mRootPath; - - public FileBrowser(String rootPath) { - Assert.isTrue(!rootPath.isEmpty(), "The rootPath cannot be empty."); - Assert.isTrue(rootPath.matches(PATH), "The format of [%s] is wrong, it should be like [/root/project]."); - this.mRootPath = rootPath; - } - - @Override - public boolean intercept(HttpRequest request) { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - return file != null; - } - - @Override - public String getETag(HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - if (file != null) { - String tag = file.getAbsolutePath() + file.lastModified(); - return DigestUtils.md5DigestAsHex(tag); - } - return null; - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - if (file != null) { - return file.lastModified(); - } - return -1; - } - - - @Override - public ResponseBody getBody(HttpRequest request, HttpResponse response) throws IOException { - String httpPath = request.getPath(); - File file = new File(mRootPath, httpPath); - if (!file.exists()) { - throw new NotFoundException(httpPath); - } - - if (file.isDirectory()) { - if (!httpPath.endsWith(File.separator)) { - String redirectPath = addEndSlash(httpPath); - response.sendRedirect(redirectPath); - return new StringBody(""); - } - - File tempFile = File.createTempFile("file_browser", ".html"); - OutputStream outputStream = new FileOutputStream(tempFile); - - String folderName = file.getName(); - String prefix = String.format(FOLDER_HTML_PREFIX, folderName, folderName); - outputStream.write(prefix.getBytes("utf-8")); - - File[] children = file.listFiles(); - if (children != null && children.length > 0) { - for (File child: children) { - String filePath = child.getAbsolutePath(); - int rootIndex = filePath.indexOf(mRootPath); - String subHttpPath = filePath.substring(rootIndex + mRootPath.length()); - subHttpPath = addStartSlash(subHttpPath); - String fileItem = String.format(FOLDER_ITEM, subHttpPath, child.getName()); - outputStream.write(fileItem.getBytes("utf-8")); - } - } - - outputStream.write(FOLDER_HTML_SUFFIX.getBytes("utf-8")); - IOUtils.closeQuietly(outputStream); - - return new FileBody(tempFile) { - - @Override - public MediaType contentType() { - MediaType mimeType = super.contentType(); - if (mimeType != null) { - mimeType = new MediaType(mimeType.getType(), mimeType.getSubtype(), StandardCharsets.UTF_8); - } - return mimeType; - } - }; - } else { - return new FileBody(file); - } - } - - /** - * Find the path specified resource. - * - * @param httpPath path. - * - * @return return if the file is found. - */ - private File findPathFile( String httpPath) { - File targetFile = new File(mRootPath, httpPath); - if (targetFile.exists()) { - return targetFile; - } - return null; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/website/StorageWebsite.java b/api/src/main/java/com/yanzhenjie/andserver/framework/website/StorageWebsite.java deleted file mode 100644 index d8072e6760cf4ce87e76df6db566efb8e669adbd..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/website/StorageWebsite.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.website; - -import com.yanzhenjie.andserver.error.NotFoundException; -import com.yanzhenjie.andserver.framework.body.FileBody; -import com.yanzhenjie.andserver.framework.body.StringBody; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.http.ResponseBody; -import com.yanzhenjie.andserver.util.Assert; -import com.yanzhenjie.andserver.util.DigestUtils; -import com.yanzhenjie.andserver.util.Patterns; -import com.yanzhenjie.andserver.util.StringUtils; - -import java.io.File; -import java.io.IOException; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public class StorageWebsite extends BasicWebsite implements Patterns { - - private final String mRootPath; - - /** - * Create a website object. - * - * @param rootPath website root directory. - */ - public StorageWebsite( String rootPath) { - this(rootPath, DEFAULT_INDEX); - } - - /** - * Create a website object. - * - * @param rootPath website root directory. - * @param indexFileName the default file name for each directory, e.g. index.html. - */ - public StorageWebsite( String rootPath, String indexFileName) { - super(indexFileName); - Assert.isTrue(!StringUtils.isEmpty(rootPath), "The rootPath cannot be empty."); - Assert.isTrue(rootPath.matches(PATH), "The format of [%s] is wrong, it should be like [/root/project]."); - - this.mRootPath = rootPath; - } - - @Override - public boolean intercept(HttpRequest request) { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - return file != null; - } - - @Override - public String getETag( HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - if (file != null) { - String tag = file.getAbsolutePath() + file.lastModified(); - return DigestUtils.md5DigestAsHex(tag); - } - return null; - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - String httpPath = request.getPath(); - File file = findPathFile(httpPath); - if (file != null) { - return file.lastModified(); - } - return -1; - } - - - @Override - public ResponseBody getBody(HttpRequest request, HttpResponse response) throws IOException { - String httpPath = request.getPath(); - File targetFile = new File(mRootPath, httpPath); - if (targetFile.exists() && targetFile.isFile()) { - return new FileBody(targetFile); - } - - File indexFile = new File(targetFile, getIndexFileName()); - if (indexFile.exists() && indexFile.isFile()) { - if (!httpPath.endsWith(File.separator)) { - String redirectPath = addEndSlash(httpPath); - String query = queryString(request); - response.sendRedirect(redirectPath + "?" + query); - return new StringBody(""); - } - - return new FileBody(indexFile); - } - throw new NotFoundException(httpPath); - } - - /** - * Find the path specified resource. - * - * @param httpPath path. - * - * @return return if the file is found. - */ - private File findPathFile( String httpPath) { - File targetFile = new File(mRootPath, httpPath); - if (targetFile.exists() && targetFile.isFile()) { - return targetFile; - } - - File indexFile = new File(targetFile, getIndexFileName()); - if (indexFile.exists() && indexFile.isFile()) { - return indexFile; - } - return null; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/framework/website/Website.java b/api/src/main/java/com/yanzhenjie/andserver/framework/website/Website.java deleted file mode 100644 index 36ace6f165ecc68964c7656b3963aee131a8ab3b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/framework/website/Website.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.framework.website; - - - -import com.yanzhenjie.andserver.framework.ETag; -import com.yanzhenjie.andserver.framework.LastModified; -import com.yanzhenjie.andserver.framework.handler.HandlerAdapter; -import com.yanzhenjie.andserver.framework.handler.RequestHandler; -import com.yanzhenjie.andserver.framework.view.BodyView; -import com.yanzhenjie.andserver.framework.view.View; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.HttpResponse; -import com.yanzhenjie.andserver.http.ResponseBody; - -import java.io.IOException; - -/** - * Created by Zhenjie Yan on 2018/9/4. - */ -public abstract class Website implements HandlerAdapter, ETag, LastModified { - - - @Override - public String getETag( HttpRequest request) throws Throwable { - return null; - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - return 0; - } - - - @Override - public RequestHandler getHandler(HttpRequest request) { - return new RequestHandler() { - - @Override - public String getETag( HttpRequest request) throws Throwable { - return Website.this.getETag(request); - } - - @Override - public long getLastModified( HttpRequest request) throws Throwable { - return Website.this.getLastModified(request); - } - - @Override - public View handle(HttpRequest request, HttpResponse response) throws Throwable { - return new BodyView(getBody(request, response)); - } - }; - } - - - public abstract ResponseBody getBody(HttpRequest request, HttpResponse response) - throws IOException; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/FAcceptLanguage.java b/api/src/main/java/com/yanzhenjie/andserver/http/FAcceptLanguage.java deleted file mode 100644 index f6dc642d967eff0942f8dfc93a9e186bc1ca02d7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/FAcceptLanguage.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - -import com.yanzhenjie.andserver.util.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018/8/7. - */ -public class FAcceptLanguage { - - private final Locale locale; - private final double quality; - - protected FAcceptLanguage(Locale locale, double quality) { - this.locale = locale; - this.quality = quality; - } - - public Locale getLocale() { - return locale; - } - - public double getQuality() { - return quality; - } - - public static List parse(String input) { - if (StringUtils.isEmpty(input)) { - return Collections.emptyList(); - } - - String[] segments = input.split(","); - if (segments.length == 0) { - return Collections.emptyList(); - } - - List list = new ArrayList<>(); - for (String segment: segments) { - String[] values = segment.split(";"); - if (values.length == 2 && values[1].length() > 2 && values[1].charAt(0) == 'q' && - values[1].charAt(1) == '=') { - String q = values[1].substring(2); - try { - list.add(new FAcceptLanguage(new Locale(values[1]), Double.parseDouble(q))); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - } - } - - return list; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/HttpContext.java b/api/src/main/java/com/yanzhenjie/andserver/http/HttpContext.java deleted file mode 100644 index a60f03b1d0a6834c087a68fb43ecffd9c44f7cdb..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/HttpContext.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - - - -/** - * Created by Zhenjie Yan on 2018/8/31. - */ -public interface HttpContext { - - String RESPONSE_PRODUCE_TYPE = "http.response.Produce"; - - String REQUEST_CREATED_SESSION = "http.request.Session"; - - String HTTP_MESSAGE_CONVERTER = "http.message.converter"; - - String ANDROID_CONTEXT = "android.context"; - - /** - * Obtains attribute with the given name. - * - * @param id the attribute name. - * - * @return attribute value, or {@code null} if not set. - */ - - Object getAttribute(String id); - - /** - * Sets value of the attribute with the given name. - * - * @param id the attribute name. - * @param obj the attribute value. - */ - void setAttribute(String id, Object obj); - - /** - * Removes attribute with the given name from the context. - * - * @param id the attribute name. - * - * @return attribute value, or {@code null} if not set. - */ - - Object removeAttribute(String id); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/HttpHeaders.java b/api/src/main/java/com/yanzhenjie/andserver/http/HttpHeaders.java deleted file mode 100644 index 2944a5b625afdd15e533e41b47bd0dea7436463f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/HttpHeaders.java +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - -/** - * Created by Zhenjie Yan on 2018/9/7. - */ -public interface HttpHeaders { - - /** - * RFC 2616 (HTTP/1.1) Section 14.1 - */ - String ACCEPT = "Accept"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.2 - */ - String ACCEPT_CHARSET = "Accept-Charset"; - - /** - * Access-Control-Allow-Credentials. - */ - String Access_Control_Allow_Credentials = "Access-Control-Allow-Credentials"; - - /** - * Access-Control-Allow-Headers. - */ - String Access_Control_Allow_Headers = "Access-Control-Allow-Headers"; - - /** - * Access-Control-Allow-Methods. - */ - String Access_Control_Allow_Methods = "Access-Control-Allow-Methods"; - - /** - * Access-Control-Allow-Origin. - */ - String Access_Control_Allow_Origin = "Access-Control-Allow-Origin"; - - /** - * Access-Control-Expose-Headers. - */ - String Access_Control_Expose_Headers = "Access-Control-Expose-Headers"; - - /** - * Access-Control-Max-Age. - */ - String Access_Control_Max_Age = "Access-Control-Max-Age"; - - /** - * Access-Control-Request-Headers. - */ - String Access_Control_Request_Headers = "Access-Control-Request-Headers"; - - /** - * Access-Control-Request-Method. - */ - String Access_Control_Request_Method = "Access-Control-Request-Method"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.3 - */ - String ACCEPT_ENCODING = "Accept-Encoding"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.4 - */ - String ACCEPT_LANGUAGE = "Accept-Language"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.5 - */ - String ACCEPT_RANGES = "Accept-Ranges"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.6 - */ - String AGE = "Age"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.1, RFC 2616 (HTTP/1.1) Section 14.7 - */ - String ALLOW = "Allow"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.2, RFC 2616 (HTTP/1.1) Section 14.8 - */ - String AUTHORIZATION = "Authorization"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.9 - */ - String CACHE_CONTROL = "Cache-Control"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.10 - */ - String CONNECTION = "Connection"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.3, RFC 2616 (HTTP/1.1) Section 14.11 - */ - String CONTENT_ENCODING = "Content-Encoding"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.12 - */ - String CONTENT_LANGUAGE = "Content-Language"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.4, RFC 2616 (HTTP/1.1) Section 14.13 - */ - String CONTENT_LENGTH = "Content-Length"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.14 - */ - String CONTENT_LOCATION = "Content-Location"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.15 - */ - String CONTENT_MD5 = "Content-MD5"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.16 - */ - String CONTENT_RANGE = "Content-Range"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.5, RFC 2616 (HTTP/1.1) Section 14.17 - */ - String CONTENT_TYPE = "Content-Type"; - - /** - * RFC 6265 (HTTP/1.0) Section 4.2 - */ - String COOKIE = "Cookie"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.6, RFC 2616 (HTTP/1.1) Section 14.18 - */ - String DATE = "Date"; - - /** - * RFC 2518 (WevDAV) Section 9.1 - */ - String DAV = "Dav"; - - /** - * RFC 2518 (WevDAV) Section 9.2 - */ - String DEPTH = "Depth"; - - /** - * RFC 2518 (WevDAV) Section 9.3 - */ - String DESTINATION = "Destination"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.19 - */ - String ETAG = "ETag"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.20 - */ - String EXPECT = "Expect"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.7, RFC 2616 (HTTP/1.1) Section 14.21 - */ - String EXPIRES = "Expires"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.8, RFC 2616 (HTTP/1.1) Section 14.22 - */ - String FROM = "From"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.23 - */ - String HOST = "Host"; - - /** - * RFC 2518 (WevDAV) Section 9.4 - */ - String IF = "If"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.24 - */ - String IF_MATCH = "If-Match"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.9, RFC 2616 (HTTP/1.1) Section 14.25 - */ - String IF_MODIFIED_SINCE = "If-Modified-Since"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.26 - */ - String IF_NONE_MATCH = "If-None-Match"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.27 - */ - String IF_RANGE = "If-Range"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.28 - */ - String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.10, RFC 2616 (HTTP/1.1) Section 14.29 - */ - String LAST_MODIFIED = "Last-Modified"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.11, RFC 2616 (HTTP/1.1) Section 14.30 - */ - String LOCATION = "Location"; - - /** - * RFC 2518 (WevDAV) Section 9.5 - */ - String LOCK_TOKEN = "Lock-Token"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.31 - */ - String MAX_FORWARDS = "Max-Forwards"; - - /** - * Origin. - */ - String ORIGIN = "Origin"; - - /** - * RFC 2518 (WevDAV) Section 9.6 - */ - String OVERWRITE = "Overwrite"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.12, RFC 2616 (HTTP/1.1) Section 14.32 - */ - String PRAGMA = "Pragma"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.33 - */ - String PROXY_AUTHENTICATE = "Proxy-Authenticate"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.34 - */ - String PROXY_AUTHORIZATION = "Proxy-Authorization"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.35 - */ - String RANGE = "Range"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.13, RFC 2616 (HTTP/1.1) Section 14.36 - */ - String REFERER = "Referer"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.37 - */ - String RETRY_AFTER = "Retry-After"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.14, RFC 2616 (HTTP/1.1) Section 14.38 - */ - String SERVER = "Server"; - - /** - * RFC 6265 (HTTP/1.0) Section 4.1, RFC 2109 (Http/1.1) Section 4.2.2 - */ - String SET_COOKIE = "Set-Cookie"; - - /** - * RFC 2518 (WevDAV) Section 9.7 - */ - String STATUS_URI = "Status-URI"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.39 - */ - String TE = "TE"; - - /** - * RFC 2518 (WevDAV) Section 9.8 - */ - String TIMEOUT = "Timeout"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.40 - */ - String TRAILER = "Trailer"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.41 - */ - String TRANSFER_ENCODING = "Transfer-Encoding"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.42 - */ - String UPGRADE = "Upgrade"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.15, RFC 2616 (HTTP/1.1) Section 14.43 - */ - String USER_AGENT = "User-Agent"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.44 - */ - String VARY = "Vary"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.45 - */ - String VIA = "Via"; - - /** - * RFC 2616 (HTTP/1.1) Section 14.46 - */ - String WARNING = "Warning"; - - /** - * RFC 1945 (HTTP/1.0) Section 10.16, RFC 2616 (HTTP/1.1) Section 14.47 - */ - String WWW_AUTHENTICATE = "WWW-Authenticate"; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/HttpMethod.java b/api/src/main/java/com/yanzhenjie/andserver/http/HttpMethod.java deleted file mode 100644 index 0000f7dc1bccccbd5f3a47ff8837b01cab107d24..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/HttpMethod.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018/8/29. - */ -public enum HttpMethod { - - GET("GET"), - HEAD("HEAD"), - POST("POST"), - PUT("PUT"), - PATCH("PATCH"), - DELETE("DELETE"), - OPTIONS("OPTIONS"), - TRACE("TRACE"); - - private String value; - - HttpMethod(String value) { - this.value = value; - } - - public String value() { - return value; - } - - /** - * Whether to allow the body to be transmitted. - * - * @return true, otherwise is false. - */ - public boolean allowBody() { - switch (this) { - case POST: - case PUT: - case PATCH: - case DELETE: - return true; - default: - return false; - } - } - - /** - * Reverse the text for the request value. - * - * @param method value text, such as: GET, POST. - * - * @return {@link HttpMethod}. - */ - public static HttpMethod reverse(String method) { - method = method.toUpperCase(Locale.ENGLISH); - switch (method) { - case "GET": { - return GET; - } - case "HEAD": { - return HEAD; - } - case "POST": { - return POST; - } - case "PUT": { - return PUT; - } - case "PATCH": { - return PATCH; - } - case "DELETE": { - return DELETE; - } - case "OPTIONS": { - return OPTIONS; - } - case "TRACE": { - return TRACE; - } - default: { - String message = String.format("The value %1$s is not supported.", method); - throw new UnsupportedOperationException(message); - } - } - } - - @Override - public String toString() { - return value; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/HttpRequest.java b/api/src/main/java/com/yanzhenjie/andserver/http/HttpRequest.java deleted file mode 100644 index 978243fd092b12c35f0e2bdc7c1c556f75618d84..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/HttpRequest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - -import com.yanzhenjie.andserver.http.cookie.Cookie; -import com.yanzhenjie.andserver.http.session.Session; -import com.yanzhenjie.andserver.util.MediaType; -import com.yanzhenjie.andserver.util.MultiValueMap; - -import java.util.Date; -import java.util.List; -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018/6/12. - */ -public interface HttpRequest extends HttpContext, HttpHeaders { - - String SESSION_NAME = "ASESSIONID"; - - /** - * Returns {@link HttpMethod} with which this request was made. - */ - - HttpMethod getMethod(); - - /** - * Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP - * request. The web container does not decode this String. - * - *

E.g. - *
First line of HTTP requestReturned Value
POST /some/path.html - * HTTP/1.1/some/path.html
GET http://foo.bar/a.html HTTP/1.0/a.html
HEAD /xyz?a=b HTTP/1.1/xyz
- */ - - String getURI(); - - /** - * Get the path to this request. - */ - - String getPath(); - - /** - * Returns an {@link List} of {@code String} objects containing the names of the query parameters contained in url of - * this request, or empty {@link List} if there are no query parameters. - * - * @return an {@link List} of {@code String}. - */ - - List getQueryNames(); - - /** - * Returns the value of a request parameter as a {@code String} object, or {@code null} if the parameter does not - * exist. - * - *

You should only use this method when you are sure the query parameter has only one value. If the query - * parameter might have more than one value, use {@link #getQueries(String)}. - * - * @param name a {@code String} specifying the name of the query parameter. - * - * @return the single value of the query parameter. - * - * @see #getQueries(String) - */ - - String getQuery(String name); - - /** - * Returns an {@link List} of {@code String} objects containing all of the values the given query parameter name, or - * empty {@link List} if the query parameter does not exist. - * - * @param name the name of the query parameter. - * - * @return an {@link List} of {@code String} containing the parameter's values. - * - * @see #getQuery(String) - */ - - List getQueries(String name); - - /** - * Returns {@link MultiValueMap} of the query parameters of this request, or empty {@link MultiValueMap} if there are no - * query parameters. - * - * @return a {@link MultiValueMap} containing query parameter names as keys and query parameter values as map values. - */ - - MultiValueMap getQuery(); - - /** - * Returns an {@link List} of all the header names this request contains, or empty {@link List} if the request has no - * headers. - */ - - List getHeaderNames(); - - /** - * Returns the value of the specified request header as a {@code String}. If the request did not include a header of the - * specified name, this method returns {@code null}. If there are multiple headers with the same name, this method - * returns the first head in the request. - * - * @param name a {@code String} specifying the header name. - * - * @see #getHeaders(String) - */ - - String getHeader(String name); - - /** - * Returns all the values of the specified request header as an {@link List} of {@code String}. - * - *

Some headers, such as {@code Accept-Language} can be sent by clients as several headers each with a different - * value rather than sending the header as a comma separated list. - * - *

If the request did not include any headers of the specified name, this method returns an empty {@link List}. - * - * @param name a {@code String} specifying the header name. - */ - - List getHeaders(String name); - - /** - * Returns the value of the specified request header as a {@code long} value that represents a {@link Date} object. Use - * this method with headers that contain dates, e.g. {@code If-Modified-Since}. - * - *

The date is returned as the number of milliseconds since January 1, 1970 GMT. The header name is case - * insensitive. - * - *

If the request did not have a header of the specified name, this method returns -1. If the header can't be - * converted to a date, the method throws an {@link IllegalStateException}. - * - * @param name a {@code String} specifying the name of the header. - */ - long getDateHeader(String name); - - /** - * Returns the value of the specified request header as an {@code int}. If the request does not have a header of the - * specified name, this method returns -1. If the header cannot be converted to an integer, this method throws a {@link - * IllegalStateException}. - * - * @param name a {@code String} specifying the name of a request header. - */ - int getIntHeader(String name); - - /** - * Returns the preferred {@link MediaType} that the client will accept content in, based on the Accept header. - */ - - MediaType getAccept(); - - /** - * Returns a {@link List} of {@link MediaType} objects indicating, in decreasing order starting with the preferred - * MediaType, the media types that are acceptable to the client based on the {@code Accept} header. If the client - * request doesn't provide an {@code Accept} header, this method returns a empty {@link List}. - * - * @return a {@link List} of {@link MediaType} objects indicating. - */ - - List getAccepts(); - - /** - * Returns the preferred {@link Locale} that the client will accept content in, based on the {@code Accept-Language} - * header. If the client request doesn't provide an {@code Accept-Language} header, this method returns the default - * locale for the server. - * - * @return the preferred {@link Locale} for the client. - */ - - Locale getAcceptLanguage(); - - /** - * Returns a {@link List} of {@link Locale} objects indicating, in decreasing order starting with the preferred {@link - * Locale}, the locales that are acceptable to the client based on the {@code Accept-Language} header. If the client - * request doesn't provide an {@code Accept-Language} header, this method returns a {@link List} containing one {@link - * Locale}, the default locale for the server. - * - * @return an {@link List} of preferred {@link Locale} objects for the client. - */ - - List getAcceptLanguages(); - - /** - * Gets the value of the cookie with the specified name. - * - * @param name the name of value. - * - * @return the value or null if the cookie with the specified name does not exist. - */ - - String getCookieValue(String name); - - /** - * Return a {@link Cookie} object, if there is no cookie corresponding to this name, it returns {@code null}. - * - * @param name cookie name. - * - * @return a {@link Cookie} object or null if there is no cookie corresponding to this name . - */ - - Cookie getCookie(String name); - - /** - * Returns an {@link List} containing all of the {@link Cookie} objects the client sent with this request. This method - * returns {@code null} if no cookies were sent. - */ - - List getCookies(); - - /** - * Returns the length, in bytes, of the request body and made available by the input stream, or -1 if the length is not - * known. - * - * @return a long containing the length of the request body or -1L if the length is not known. - */ - long getContentLength(); - - /** - * Returns the MIME type of the body of the request, or {@code null} if the type is not known. - * - * @return a {@code String} containing the name of the MIME type of the request, or null if the type is not known. - */ - - MediaType getContentType(); - - /** - * Returns an {@link List} of {@code String} containing the names of the parameters contained in this request. If the - * request has no parameters, the method returns an empty {@link List}. - * - * @return an {@link List} of {@code String} objects. - */ - - List getParameterNames(); - - /** - * Returns the value of a request parameter as a {@code String}, or {@code null} if the parameter does not exist. - * - *

You should only use this method when you are sure the parameter has only one value. If the parameter might - * have more than one value, use {@link #getParameters(String)}. - * - * @param name a {@code String} specifying the name of the parameter. - * - * @return the single value of the parameter. - * - * @see #getParameters(String) - */ - - String getParameter(String name); - - /** - * Returns an array of {@code String} objects containing all of the values the given request parameter has, or {@code - * null} if the parameter does not exist. - * - * @param name a {@code String} containing the name of the parameter whose value is requested. - * - * @return an array of {@code String} objects containing the parameter's values. - * - * @see #getParameter(String) - */ - - List getParameters(String name); - - /** - * Returns {@link MultiValueMap} of the parameters of this request, or empty {@link MultiValueMap} if there are no - * parameters. - * - * @return a {@link MultiValueMap} containing parameter names as keys and parameter values as map values. - */ - - MultiValueMap getParameter(); - - /** - * Get the response body. - * - * @return {@link RequestBody}. - * - * @throws UnsupportedOperationException if the request method does not allow the body to be sent. - */ - - RequestBody getBody(); - - /** - * Returns the current {@code Session} associated with this request or, if there is no current session returns a new - * session. - * - * @return the session associated with this request or a new session. - * - * @see #getSession() - */ - - Session getValidSession(); - - /** - * Returns the current session associated with this request, or if the request does not have a session, creates one. - * - * @see #getValidSession() - */ - - Session getSession(); - - /** - * Change the session id of the current session associated with this request and return the new session id, if there is - * no session associated with the request, an {@link IllegalStateException} is thrown. - * - * @return the new session id. - * - * @see #getSession() - * @see #getValidSession() - */ - - String changeSessionId(); - - /** - * Checks whether the requested session ID is still valid. - * - *

If the client did not specify any session ID, this method returns {@code false}. - * - * @see #getSession() - * @see #getValidSession() - */ - boolean isSessionValid(); - - /** - * Returns a {@link RequestDispatcher} object that acts as a wrapper for the resource located at the given path. - * - * @return a {@link RequestDispatcher} object or null if the handler corresponding to the path is not - * found. - */ - - RequestDispatcher getRequestDispatcher(String path); - - /** - * Get the http context of this request. - * - * @return {@link HttpContext}. - */ - HttpContext getContext(); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/HttpResponse.java b/api/src/main/java/com/yanzhenjie/andserver/http/HttpResponse.java deleted file mode 100644 index 9074c6d0d56dc16e059463c5d2e1a07ab94eec2c..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/HttpResponse.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.http.cookie.Cookie; - -import java.util.Enumeration; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/6/12. - */ -public interface HttpResponse extends StatusCode, HttpHeaders { - - /** - * Sets the status code for this response. - * - *

This method preserves any cookies and other response headers. - * - *

Valid status codes are those in the 2XX, 3XX, 4XX, and 5XX ranges. Other status codes will be considered to be - * specific. - */ - void setStatus(int sc); - - /** - * Gets the current status code of this response. - * - * @return status code. - */ - int getStatus(); - - /** - * Sets a response header with the given name and value. If the header had already been set, the new value overwrites - * the previous one. The {@link #containsHeader(String)} method can be used to test for the presence of a header before - * setting its value. - * - * @see #containsHeader(String) - * @see #addHeader(String, String) - */ - void setHeader(String name, String value); - - /** - * Adds a response header with the given name and value. This method allows response headers to have multiple values. - * - * @see #setHeader(String, String) - */ - void addHeader(String name, String value); - - /** - * Gets the value of the response header with the given name. - * - *

If a response header with the given name exists and contains multiple values, the value that was added first - * will be returned. - * - * @param name the name of the response header. - * - * @return the value of the response header with the given name, or {@code null} if no header with the given name has - * been set on this response. - */ - - String getHeader(String name); - - /** - * Sets a response header with the given name and date-value. The date is specified in terms of milliseconds since the - * epoch. - * - *

If the header had already been set, the new value overwrites the previous one. The {@link - * #containsHeader(String)} method can be used to test for the presence of a header before setting its value. - * - * @see #containsHeader(String) - * @see #addDateHeader(String, long) - */ - void setDateHeader(String name, long date); - - /** - * Adds a response header with the given name and date-value. The date is specified in terms of milliseconds since the - * epoch. This method allows response headers to have multiple values. - * - * @see #setDateHeader(String, long) - */ - void addDateHeader(String name, long date); - - /** - * Sets a response header with the given name and integer value. If the header had already been set, the new value - * overwrites the previous one. The {@link #containsHeader(String)} method can be used to test for the presence of a - * header before setting its value. - * - * @see #containsHeader(String) - * @see #addIntHeader(String, int) - */ - void setIntHeader(String name, int value); - - /** - * Adds a response header with the given name and integer value. This method allows response headers to have multiple - * values. - * - * @see #setIntHeader(String, int) - */ - void addIntHeader(String name, int value); - - /** - * Returns a boolean indicating whether the named response header has already been set. - */ - boolean containsHeader(String name); - - /** - * Gets the values of the response header with the given name. - * - * @param name the name of the response header. - * - * @return a {@link List} of the values of the response header with the given name. - */ - - List getHeaders(String name); - - /** - * Gets the names of the headers of this response. - * - * @return a {@link Enumeration} of the names of the headers of this response. - */ - - List getHeaderNames(); - - /** - * Adds the specified cookie to the response. This method can be called multiple times to set more than one cookie. - * - * @param cookie the cookie to return to the client. - */ - void addCookie(Cookie cookie); - - /** - * Sends a temporary redirect response to the client using the specified redirect location URL and clears the buffer. - * The buffer will be replaced with the data set by this method. Calling this method sets the status code to {@link - * StatusCode#SC_FOUND}. - */ - void sendRedirect(String location); - - /** - * Set the response body. - * - * @param body write the message content sent to the client. - */ - void setBody(ResponseBody body); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/Modified.java b/api/src/main/java/com/yanzhenjie/andserver/http/Modified.java deleted file mode 100644 index 4cb9ced59c97ff7af90dd0149024c5e56e59ab5f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/Modified.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - -import com.yanzhenjie.andserver.util.StringUtils; - -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.yanzhenjie.andserver.util.HttpDateFormat.parseDate; - -/** - * Created by Zhenjie Yan on 2018/8/29. - */ -public class Modified implements HttpHeaders { - - private static final Pattern ETAG_PATTERN = Pattern.compile("\\*|\\s*((W\\/)?(\"[^\"]*\"))\\s*,?"); - - private HttpRequest mRequest; - private HttpResponse mResponse; - - private boolean isNotModified; - - public Modified( HttpRequest request, HttpResponse response) { - this.mRequest = request; - this.mResponse = response; - } - - /** - * Process {@code Modified} according to given the supplied {@code Last-Modified}. - * - * @param lastModified the last-modified timestamp in milliseconds of the resource. - * - * @return true if the request does not require further processing. - */ - public boolean process(long lastModified) { - return process(null, lastModified); - } - - /** - * Process {@code Modified} according to given the supplied {@code ETag}. - * - * @param eTag the tag of the resource. - * - * @return true if the request does not require further processing. - */ - public boolean process(String eTag) { - return process(eTag, -1); - } - - /** - * Process {@code Modified} according to given the supplied {@code Last-Modified} and {@code ETag}. - * - * @param eTag the tag of the resource. - * @param lastModified he last-modified timestamp in milliseconds of the resource. - * - * @return true if the request does not require further processing. - */ - public boolean process(String eTag, long lastModified) { - if (isNotModified) { - return true; - } - - // See https://tools.ietf.org/html/rfc7232#section-6 - if (validateIfUnmodifiedSince(lastModified)) { - if (!isNotModified) { - mResponse.setStatus(StatusCode.SC_LENGTH_REQUIRED); - } - return isNotModified; - } - - // First, prioritized. - boolean validated = validateIfNoneMatch(eTag); - // Second. - if (!validated) { - validateIfModifiedSince(lastModified); - } - - // Update response - HttpMethod method = mRequest.getMethod(); - boolean isGetHead = (method == HttpMethod.GET || method == HttpMethod.HEAD); - if (isNotModified) { - mResponse.setStatus(isGetHead ? StatusCode.SC_NOT_MODIFIED : StatusCode.SC_LENGTH_REQUIRED); - } - if (isGetHead) { - if (lastModified > 0 && mResponse.getHeader(LAST_MODIFIED) == null) { - mResponse.setDateHeader(LAST_MODIFIED, lastModified); - } - if (!StringUtils.isEmpty(eTag) && mResponse.getHeader(ETAG) == null) { - mResponse.setHeader(ETAG, padETagIfNecessary(eTag)); - } - mResponse.setHeader(CACHE_CONTROL, "private"); - } - return isNotModified; - } - - private boolean validateIfNoneMatch(String eTag) { - if (StringUtils.isEmpty(eTag)) { - return false; - } - - List ifNoneMatch = mRequest.getHeaders(IF_NONE_MATCH); - if (ifNoneMatch.isEmpty()) { - return false; - } - - // We will perform this validation... - eTag = padETagIfNecessary(eTag); - for (String clientETags: ifNoneMatch) { - Matcher eTagMatcher = ETAG_PATTERN.matcher(clientETags); - // Compare weak/strong ETags as per https://tools.ietf.org/html/rfc7232#section-2.3 - while (eTagMatcher.find()) { - if (!StringUtils.isEmpty(eTagMatcher.group()) && - eTag.replaceFirst("^W/", "").equals(eTagMatcher.group(3))) { - isNotModified = true; - break; - } - } - } - return true; - } - - private String padETagIfNecessary(String eTag) { - if (StringUtils.isEmpty(eTag)) { - return eTag; - } - if ((eTag.startsWith("\"") || eTag.startsWith("W/\"")) && eTag.endsWith("\"")) { - return eTag; - } - return "\"" + eTag + "\""; - } - - private boolean validateIfModifiedSince(long lastModifiedTimestamp) { - if (lastModifiedTimestamp < 0) { - return false; - } - - long ifModifiedSince = parseDateHeader(IF_MODIFIED_SINCE); - if (ifModifiedSince == -1) { - return false; - } - - // We will perform this validation... - isNotModified = ifModifiedSince >= lastModifiedTimestamp; - return true; - } - - private boolean validateIfUnmodifiedSince(long lastModifiedTimestamp) { - if (lastModifiedTimestamp < 0) { - return false; - } - long ifUnmodifiedSince = parseDateHeader(IF_UNMODIFIED_SINCE); - if (ifUnmodifiedSince == -1) { - return false; - } - // We will perform this validation... - isNotModified = ifUnmodifiedSince >= lastModifiedTimestamp; - return true; - } - - private long parseDateHeader(String headerName) { - long dateValue = -1; - try { - dateValue = mRequest.getDateHeader(headerName); - } catch (IllegalStateException ex) { - String headerValue = mRequest.getHeader(headerName); - if (StringUtils.isEmpty(headerValue)) { - return -1; - } - // Possibly an IE 10 style value: "Wed, 09 Apr 2014 09:57:42 GMT; length=13774" - int separatorIndex = headerValue.indexOf(';'); - if (separatorIndex != -1) { - String datePart = headerValue.substring(0, separatorIndex); - dateValue = parseDateValue(datePart); - } - } - return dateValue; - } - - private long parseDateValue(String headerValue) { - if (headerValue == null) { - return -1; - } - - if (headerValue.length() >= 3) { - // Short "0" or "-1" like values are never valid HTTP date headers... - // Let's only bother with SimpleDateFormat parsing for long enough values. - return parseDate(headerValue); - } - return -1; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/RequestBody.java b/api/src/main/java/com/yanzhenjie/andserver/http/RequestBody.java deleted file mode 100644 index 20dc7185004608d45ed6f5b52ba1e0ae6b30b71b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/RequestBody.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.util.MediaType; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public interface RequestBody { - - /** - * Retrieve the character encoding for the request. - * - * @return the character encoding for the request. - */ - String contentEncoding(); - - /** - * Get the {@code Content-Length} of the message body, if the length is unknown, return a negative value. - * - * @return message length. - */ - long length(); - - /** - * Get the {@code Content-Type} of the message body, including charset. - * - * @return e.g. {@code application/json; charset=utf-8}, or {@code null} if the content type is unknown. - */ - - MediaType contentType(); - - /** - * Returns a content stream of this body. - * - * @return content stream of this body. - * - * @throws IOException if the stream could not be created. - */ - - InputStream stream() throws IOException; - - /** - * Convert the request body to a String. - * - * @return string. - * - * @throws IOException if the stream could not be created. - */ - - String string() throws IOException; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/RequestDispatcher.java b/api/src/main/java/com/yanzhenjie/andserver/http/RequestDispatcher.java deleted file mode 100644 index 04c2dd51cd568b346faa2c34c6341fc3bcc6fd61..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/RequestDispatcher.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - - -/** - * Created by Zhenjie Yan on 2018/8/31. - */ -public interface RequestDispatcher { - - /** - * Forwards a request from a handler to another handler on the server. - * - * @param request the current request. - * @param response the current response. - */ - void forward(HttpRequest request, HttpResponse response); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/RequestWrapper.java b/api/src/main/java/com/yanzhenjie/andserver/http/RequestWrapper.java deleted file mode 100644 index e05297969f71ece54cbc2ec95f83868d3f46e0c3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/RequestWrapper.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.http.cookie.Cookie; -import com.yanzhenjie.andserver.http.session.Session; -import com.yanzhenjie.andserver.util.MediaType; -import com.yanzhenjie.andserver.util.MultiValueMap; - -import java.util.List; -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018/9/6. - */ -public class RequestWrapper implements HttpRequest { - - private HttpRequest mRequest; - - public RequestWrapper(HttpRequest request) { - this.mRequest = request; - } - - /** - * Get the original request object. - * - * @return {@link HttpRequest}. - */ - public HttpRequest getRequest() { - return mRequest; - } - - - @Override - public HttpMethod getMethod() { - return mRequest.getMethod(); - } - - - @Override - public String getURI() { - return mRequest.getURI(); - } - - - @Override - public String getPath() { - return mRequest.getPath(); - } - - - @Override - public List getQueryNames() { - return mRequest.getQueryNames(); - } - - - @Override - public String getQuery( String name) { - return mRequest.getQuery(name); - } - - - @Override - public List getQueries( String name) { - return mRequest.getQueries(name); - } - - - @Override - public MultiValueMap getQuery() { - return mRequest.getQuery(); - } - - - @Override - public List getHeaderNames() { - return mRequest.getHeaderNames(); - } - - - @Override - public String getHeader( String name) { - return mRequest.getHeader(name); - } - - - @Override - public List getHeaders( String name) { - return mRequest.getHeaders(name); - } - - @Override - public long getDateHeader( String name) { - return mRequest.getDateHeader(name); - } - - @Override - public int getIntHeader( String name) { - return mRequest.getIntHeader(name); - } - - - @Override - public MediaType getAccept() { - return mRequest.getAccept(); - } - - - @Override - public List getAccepts() { - return mRequest.getAccepts(); - } - - - @Override - public Locale getAcceptLanguage() { - return mRequest.getAcceptLanguage(); - } - - - @Override - public List getAcceptLanguages() { - return mRequest.getAcceptLanguages(); - } - - - @Override - public String getCookieValue(String name) { - return mRequest.getCookieValue(name); - } - - - @Override - public Cookie getCookie(String name) { - return mRequest.getCookie(name); - } - - - @Override - public List getCookies() { - return mRequest.getCookies(); - } - - @Override - public long getContentLength() { - return mRequest.getContentLength(); - } - - - @Override - public MediaType getContentType() { - return mRequest.getContentType(); - } - - - @Override - public List getParameterNames() { - return mRequest.getParameterNames(); - } - - - @Override - public String getParameter( String name) { - return mRequest.getParameter(name); - } - - - @Override - public List getParameters( String name) { - return mRequest.getParameters(name); - } - - - @Override - public MultiValueMap getParameter() { - return mRequest.getParameter(); - } - - - @Override - public RequestBody getBody() throws UnsupportedOperationException { - return mRequest.getBody(); - } - - - @Override - public Session getValidSession() { - return mRequest.getValidSession(); - } - - - @Override - public Session getSession() { - return mRequest.getSession(); - } - - - @Override - public String changeSessionId() { - return mRequest.changeSessionId(); - } - - @Override - public boolean isSessionValid() { - return mRequest.isSessionValid(); - } - - - @Override - public RequestDispatcher getRequestDispatcher( String path) { - return mRequest.getRequestDispatcher(path); - } - - @Override - public HttpContext getContext() { - return mRequest.getContext(); - } - - - @Override - public Object getAttribute( String id) { - return mRequest.getAttribute(id); - } - - @Override - public void setAttribute( String id, Object obj) { - mRequest.setAttribute(id, obj); - } - - - @Override - public Object removeAttribute( String id) { - return mRequest.removeAttribute(id); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/ResponseBody.java b/api/src/main/java/com/yanzhenjie/andserver/http/ResponseBody.java deleted file mode 100644 index fede7df0e548b458a4b237eff56037dd79fc3ef1..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/ResponseBody.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.util.MediaType; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * Created by Zhenjie Yan on 2018/8/3. - */ -public interface ResponseBody { - - /** - * Can it be reused? - * - * @return true, otherwise is false. - */ - boolean isRepeatable(); - - /** - * Get the content-length of the message body, if the length is unknown, return a negative value. - * - * @return message length. - */ - long contentLength(); - - /** - * Get the content-type of the message body, including charset. - * - * @return e.g. {@code application/json; charset=utf-8}. - */ - - MediaType contentType(); - - /** - * Write the body to the output stream. - * - * @param output the output stream to write the body. - */ - void writeTo(OutputStream output) throws IOException; - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/ResponseWrapper.java b/api/src/main/java/com/yanzhenjie/andserver/http/ResponseWrapper.java deleted file mode 100644 index b00f5d434e4bce975f3041991da77f64049f6d7e..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/ResponseWrapper.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.http.cookie.Cookie; - -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/9/6. - */ -public class ResponseWrapper implements HttpResponse { - - private HttpResponse mResponse; - - public ResponseWrapper(HttpResponse response) { - this.mResponse = response; - } - - /** - * Get the original response object. - * - * @return {@link HttpResponse}. - */ - public HttpResponse getResponse() { - return mResponse; - } - - @Override - public void setStatus(int sc) { - mResponse.setStatus(sc); - } - - @Override - public int getStatus() { - return mResponse.getStatus(); - } - - @Override - public void setHeader( String name, String value) { - mResponse.setHeader(name, value); - } - - @Override - public void addHeader( String name, String value) { - mResponse.addHeader(name, value); - } - - - @Override - public String getHeader( String name) { - return mResponse.getHeader(name); - } - - @Override - public void setDateHeader( String name, long date) { - mResponse.setDateHeader(name, date); - } - - @Override - public void addDateHeader( String name, long date) { - mResponse.addDateHeader(name, date); - } - - @Override - public void setIntHeader( String name, int value) { - mResponse.setIntHeader(name, value); - } - - @Override - public void addIntHeader( String name, int value) { - mResponse.addIntHeader(name, value); - } - - @Override - public boolean containsHeader( String name) { - return mResponse.containsHeader(name); - } - - - @Override - public List getHeaders( String name) { - return mResponse.getHeaders(name); - } - - - @Override - public List getHeaderNames() { - return mResponse.getHeaderNames(); - } - - @Override - public void addCookie( Cookie cookie) { - mResponse.addCookie(cookie); - } - - @Override - public void sendRedirect( String location) { - mResponse.sendRedirect(location); - } - - @Override - public void setBody(ResponseBody body) { - mResponse.setBody(body); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/StandardContext.java b/api/src/main/java/com/yanzhenjie/andserver/http/StandardContext.java deleted file mode 100644 index 4b91ebda7a9a3cdf6e56a6eee484b6ac7cacf431..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/StandardContext.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - - - -/** - * Created by Zhenjie Yan on 2018/8/31. - */ -public class StandardContext implements HttpContext { - - private org.apache.httpcore.protocol.HttpContext mContext; - - public StandardContext(org.apache.httpcore.protocol.HttpContext context) { - this.mContext = context; - } - - - @Override - public Object getAttribute( String id) { - return mContext.getAttribute(id); - } - - @Override - public void setAttribute( String id, Object obj) { - mContext.setAttribute(id, obj); - } - - - @Override - public Object removeAttribute( String id) { - return mContext.removeAttribute(id); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/StandardRequest.java b/api/src/main/java/com/yanzhenjie/andserver/http/StandardRequest.java deleted file mode 100644 index ab7d1886437f55d619d9d06a4db4cdb7629942a2..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/StandardRequest.java +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - -import com.yanzhenjie.andserver.DispatcherHandler; -import com.yanzhenjie.andserver.http.cookie.Cookie; -import com.yanzhenjie.andserver.http.cookie.CookieProcessor; -import com.yanzhenjie.andserver.http.cookie.StandardCookieProcessor; -import com.yanzhenjie.andserver.http.session.Session; -import com.yanzhenjie.andserver.http.session.SessionManager; -import com.yanzhenjie.andserver.util.*; -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.HttpEntityEnclosingRequest; -import org.apache.httpcore.RequestLine; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.zip.GZIPInputStream; - -/** - * Created by Zhenjie Yan on 2018/6/12. - */ -public class StandardRequest implements HttpRequest { - - private static final CookieProcessor COOKIE_PROCESSOR = new StandardCookieProcessor(); - - private org.apache.httpcore.HttpRequest mRequest; - private HttpContext mContext; - private DispatcherHandler mHandler; - private RequestLine mRequestLine; - private SessionManager mSessionManager; - - private Uri mUri; - private boolean isParsedUri; - - private MultiValueMap mQuery; - private boolean isParsedQuery; - - private List mAccepts; - private boolean isParsedAccept; - - private List mLocales; - private boolean isParsedLocale; - - private MultiValueMap mParameter; - private boolean isParsedParameter; - - public StandardRequest(org.apache.httpcore.HttpRequest request, HttpContext context, DispatcherHandler handler, - SessionManager sessionManager) { - this.mRequest = request; - this.mContext = context; - this.mHandler = handler; - this.mRequestLine = request.getRequestLine(); - this.mSessionManager = sessionManager; - } - - - @Override - public HttpMethod getMethod() { - return HttpMethod.reverse(mRequestLine.getMethod()); - } - - - @Override - public String getURI() { - parseUri(); - return mUri.toString(); - } - - private void parseUri() { - if (isParsedUri) { - return; - } - - String requestLine = mRequestLine.getUri(); - if (StringUtils.isEmpty(requestLine)) { - requestLine = "/"; - } - - String uri = "scheme://host:ip" + requestLine; - mUri = Uri.newBuilder(uri).build(); - isParsedUri = true; - } - - public void setPath(String path) { - parseUri(); - mUri = mUri.builder().setPath(path).build(); - } - - - @Override - public String getPath() { - parseUri(); - return mUri.getPath(); - } - - - @Override - public List getQueryNames() { - parseQuery(); - return new LinkedList<>(mQuery.keySet()); - } - - - @Override - public String getQuery( String name) { - parseQuery(); - return mQuery.getFirst(name); - } - - - @Override - public List getQueries( String name) { - parseQuery(); - List values = mQuery.get(name); - return (values == null || values.isEmpty()) ? Collections.emptyList() : values; - } - - - @Override - public MultiValueMap getQuery() { - parseQuery(); - return mQuery; - } - - private void parseQuery() { - if (isParsedQuery) { - return; - } - parseUri(); - - mQuery = mUri.getParams(); - isParsedQuery = true; - } - - - @Override - public List getHeaderNames() { - Header[] headers = mRequest.getAllHeaders(); - if (headers == null || headers.length == 0) { - return Collections.emptyList(); - } - - List nameList = new ArrayList<>(); - for (Header header: headers) { - nameList.add(header.getName()); - } - return nameList; - } - - - @Override - public String getHeader( String name) { - Header header = mRequest.getFirstHeader(name); - return header == null ? null : header.getValue(); - } - - - @Override - public List getHeaders( String name) { - Header[] headers = mRequest.getHeaders(name); - if (headers == null || headers.length == 0) { - return Collections.emptyList(); - } - - List valueList = new ArrayList<>(); - for (Header header: headers) { - valueList.add(header.getValue()); - } - return valueList; - } - - @Override - public long getDateHeader( String name) { - Header header = mRequest.getFirstHeader(name); - if (header == null) { - return -1; - } - - String value = header.getValue(); - long date = HttpDateFormat.parseDate(value); - - if (date == -1) { - String message = String.format("The %s cannot be converted to date.", value); - throw new IllegalStateException(message); - } - - return date; - } - - @Override - public int getIntHeader( String name) { - Header header = mRequest.getFirstHeader(name); - if (header == null) { - return -1; - } - - try { - return Integer.parseInt(header.getValue()); - } catch (NumberFormatException e) { - throw new IllegalStateException(e.getMessage(), e); - } - } - - - @Override - public MediaType getAccept() { - List mediaTypes = getAccepts(); - return mediaTypes.isEmpty() ? null : mediaTypes.get(0); - } - - - @Override - public List getAccepts() { - parseAccept(); - return mAccepts; - } - - private void parseAccept() { - if (isParsedAccept) { - return; - } - - mAccepts = new ArrayList<>(); - Header[] headers = mRequest.getHeaders(ACCEPT); - if (headers != null && headers.length > 0) { - for (Header header: headers) { - List mediaTypes = MediaType.parseMediaTypes(header.getValue()); - mAccepts.addAll(mediaTypes); - } - } - if (mAccepts.isEmpty()) { - mAccepts.add(MediaType.ALL); - } - - isParsedAccept = true; - } - - - @Override - public Locale getAcceptLanguage() { - return getAcceptLanguages().get(0); - } - - - @Override - public List getAcceptLanguages() { - parseLocale(); - return mLocales; - } - - private void parseLocale() { - if (isParsedLocale) { - return; - } - - mLocales = new ArrayList<>(); - Header[] headers = mRequest.getHeaders(ACCEPT_LANGUAGE); - if (headers != null && headers.length > 0) { - for (Header header: headers) { - List acceptLanguages = FAcceptLanguage.parse(header.getValue()); - for (FAcceptLanguage acceptLanguage: acceptLanguages) { - mLocales.add(acceptLanguage.getLocale()); - } - } - } - if (mLocales.isEmpty()) { - mLocales.add(Locale.getDefault()); - } - - isParsedLocale = true; - } - - - @Override - public String getCookieValue(String name) { - Cookie cookie = getCookie(name); - if (cookie != null) { - return cookie.getValue(); - } - return null; - } - - - @Override - public Cookie getCookie(String name) { - List cookies = getCookies(); - if (cookies.isEmpty()) { - return null; - } - - for (Cookie cookie: cookies) { - if (name.equalsIgnoreCase(cookie.getName())) { - return cookie; - } - } - return null; - } - - - @Override - public List getCookies() { - return COOKIE_PROCESSOR.parseCookieHeader(mRequest.getHeaders(COOKIE)); - } - - @Override - public long getContentLength() { - String contentLength = getHeader(CONTENT_LENGTH); - if (StringUtils.isEmpty(contentLength)) { - return -1; - } - try { - return Long.parseLong(contentLength); - } catch (NumberFormatException e) { - return -1; - } - } - - - @Override - public MediaType getContentType() { - String contentType = getHeader(CONTENT_TYPE); - if (contentType.isEmpty()) { - return null; - } - return MediaType.valueOf(contentType); - } - - - @Override - public List getParameterNames() { - parseParameter(); - List paramNames = new LinkedList<>(mParameter.keySet()); - List names = getQueryNames(); - if (!names.isEmpty()) { - paramNames.addAll(names); - } - return paramNames; - } - - - @Override - public String getParameter( String name) { - parseParameter(); - String value = mParameter.getFirst(name); - return value.isEmpty() ? getQuery(name) : value; - } - - - @Override - public List getParameters( String name) { - parseParameter(); - List values = mParameter.get(name); - if (values == null || values.isEmpty()) { - return getQueries(name); - } - return values; - } - - - @Override - public MultiValueMap getParameter() { - parseParameter(); - return mParameter.isEmpty() ? getQuery() : mParameter; - } - - private void parseParameter() { - if (isParsedParameter) { - return; - } - - if (!getMethod().allowBody()) { - mParameter = new LinkedMultiValueMap<>(); - return; - } - - MediaType mediaType = getContentType(); - if (MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType)) { - try { - RequestBody body = getBody(); - String bodyString = body == null ? "" : body.string(); - mParameter = parseParameters(bodyString); - } catch (Exception ignored) { - } - } - if (mParameter == null) { - mParameter = new LinkedMultiValueMap<>(); - } - isParsedParameter = true; - } - - - @Override - public RequestBody getBody() { - if (getMethod().allowBody()) { - if (mRequest instanceof HttpEntityEnclosingRequest) { - HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) mRequest; - HttpEntity entity = request.getEntity(); - if (entity == null) { - return null; - } - return new EntityToBody(entity); - } - return null; - } - throw new UnsupportedOperationException("This method does not allow body."); - } - - - @Override - public Session getValidSession() { - Session session = getSession(); - if (session == null) { - session = mSessionManager.createSession(); - } else if (session.isValid()) { - session = mSessionManager.createSession(); - } - - setAttribute(REQUEST_CREATED_SESSION, session); - return session; - } - - @Override - public Session getSession() { - Object objSession = getAttribute(REQUEST_CREATED_SESSION); - if (objSession instanceof Session) { - return (Session) objSession; - } - - List cookies = getCookies(); - if (cookies.isEmpty()) { - return null; - } - - String sessionId = null; - for (Cookie cookie: cookies) { - if (SESSION_NAME.equalsIgnoreCase(cookie.getName())) { - sessionId = cookie.getValue(); - break; - } - } - - if (sessionId.isEmpty()) { - return null; - } - - Session session = null; - try { - session = mSessionManager.findSession(sessionId); - } catch (IOException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - - return session; - } - - @Override - public String changeSessionId() { - Session session = getSession(); - if (session == null) { - throw new IllegalStateException("No session associated with this request."); - } - mSessionManager.changeSessionId(session); - return session.getId(); - } - - @Override - public boolean isSessionValid() { - Session session = getSession(); - return session != null && session.isValid(); - } - - - @Override - public RequestDispatcher getRequestDispatcher(String path) { - return mHandler.getRequestDispatcher(this, path); - } - - @Override - public HttpContext getContext() { - return mContext; - } - - - @Override - public Object getAttribute(String id) { - return mContext.getAttribute(id); - } - - @Override - public void setAttribute( String id, Object obj) { - mContext.setAttribute(id, obj); - } - - - @Override - public Object removeAttribute( String id) { - return mContext.removeAttribute(id); - } - - - private static MultiValueMap parseParameters(String input) { - MultiValueMap parameters = new LinkedMultiValueMap<>(); - StringTokenizer tokenizer = new StringTokenizer(input, "&"); - while (tokenizer.hasMoreElements()) { - String element = tokenizer.nextToken(); - int end = element.indexOf("="); - - if (end > 0 && end < element.length() - 1) { - String key = element.substring(0, end); - String value = element.substring(end + 1); - parameters.add(key, UrlCoder.urlDecode(value, StandardCharsets.UTF_8)); - } - } - return parameters; - } - - private static class EntityToBody implements RequestBody { - - private HttpEntity mEntity; - - private EntityToBody(HttpEntity entity) { - this.mEntity = entity; - } - - @Override - public String contentEncoding() { - Header encoding = mEntity.getContentType(); - return encoding == null ? "" : encoding.getValue(); - } - - @Override - public long length() { - return mEntity.getContentLength(); - } - - - @Override - public MediaType contentType() { - Header header = mEntity.getContentType(); - if (header == null) { - return null; - } - - String contentType = header.getValue(); - return MediaType.valueOf(contentType); - } - - - @Override - public InputStream stream() throws IOException { - InputStream stream = mEntity.getContent(); - if (contentEncoding().toLowerCase().contains("gzip")) { - stream = new GZIPInputStream(stream); - } - return stream; - } - - - @Override - public String string() throws IOException { - MimeType mimeType = contentType(); - Charset charset = mimeType == null ? null : mimeType.getCharset(); - - if (charset == null) { - return IOUtils.toString(stream()); - } else { - return IOUtils.toString(stream(), charset); - } - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/StandardResponse.java b/api/src/main/java/com/yanzhenjie/andserver/http/StandardResponse.java deleted file mode 100644 index cbac08aa2037de1a2026cd5523aa920a56ff0480..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/StandardResponse.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - -import com.yanzhenjie.andserver.http.cookie.Cookie; -import com.yanzhenjie.andserver.http.cookie.CookieProcessor; -import com.yanzhenjie.andserver.http.cookie.StandardCookieProcessor; -import com.yanzhenjie.andserver.util.HttpDateFormat; -import com.yanzhenjie.andserver.util.MediaType; -import org.apache.httpcore.Header; -import org.apache.httpcore.HttpEntity; -import org.apache.httpcore.message.BasicHeader; -import org.apache.httpcore.util.EntityUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/6/12. - */ -public class StandardResponse implements HttpResponse { - - private static final CookieProcessor COOKIE_PROCESSOR = new StandardCookieProcessor(); - - private org.apache.httpcore.HttpResponse mResponse; - - public StandardResponse(org.apache.httpcore.HttpResponse response) { - this.mResponse = response; - } - - @Override - public void setStatus(int sc) { - mResponse.setStatusCode(sc); - } - - @Override - public int getStatus() { - return mResponse.getStatusLine().getStatusCode(); - } - - @Override - public void setHeader( String name, String value) { - mResponse.setHeader(name, value); - } - - @Override - public void addHeader( String name, String value) { - mResponse.addHeader(name, value); - } - - - @Override - public String getHeader( String name) { - Header header = mResponse.getFirstHeader(name); - return header == null ? null : header.getValue(); - } - - @Override - public void setDateHeader( String name, long date) { - setHeader(name, HttpDateFormat.formatDate(date)); - } - - @Override - public void addDateHeader( String name, long date) { - addHeader(name, HttpDateFormat.formatDate(date)); - } - - @Override - public void setIntHeader( String name, int value) { - setHeader(name, Integer.toString(value)); - } - - @Override - public void addIntHeader( String name, int value) { - addHeader(name, Integer.toString(value)); - } - - @Override - public boolean containsHeader( String name) { - return mResponse.containsHeader(name); - } - - - @Override - public List getHeaders( String name) { - Header[] headers = mResponse.getHeaders(name); - if (headers == null || headers.length == 0) { - return Collections.emptyList(); - } - - List list = new ArrayList<>(); - for (Header header: headers) { - list.add(header.getValue()); - } - return list; - } - - - @Override - public List getHeaderNames() { - Header[] headers = mResponse.getAllHeaders(); - if (headers == null || headers.length == 0) { - return Collections.emptyList(); - } - - List list = new ArrayList<>(); - for (Header header: headers) { - list.add(header.getName()); - } - return list; - } - - @Override - public void addCookie( Cookie cookie) { - addHeader(SET_COOKIE, COOKIE_PROCESSOR.generateHeader(cookie)); - } - - @Override - public void sendRedirect( String location) { - setStatus(SC_FOUND); - setHeader(LOCATION, location); - } - - @Override - public void setBody(ResponseBody body) { - mResponse.setEntity(new BodyToEntity(body)); - } - - private static class BodyToEntity implements HttpEntity { - - private ResponseBody mBody; - - private BodyToEntity(ResponseBody body) { - this.mBody = body; - } - - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public boolean isChunked() { - return false; - } - - @Override - public long getContentLength() { - return mBody.contentLength(); - } - - @Override - public Header getContentType() { - MediaType mimeType = mBody.contentType(); - if (mimeType == null) { - return null; - } - return new BasicHeader(CONTENT_TYPE, mimeType.toString()); - } - - @Override - public Header getContentEncoding() { - return null; - } - - @Override - public InputStream getContent() throws IOException { - return null; - } - - @Override - public void writeTo(OutputStream out) throws IOException { - mBody.writeTo(out); - } - - @Override - public boolean isStreaming() { - return false; - } - - @Override - public void consumeContent() { - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/StatusCode.java b/api/src/main/java/com/yanzhenjie/andserver/http/StatusCode.java deleted file mode 100644 index 9247a36b3322c2ab7a98086654ae4e404bf8efc6..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/StatusCode.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public interface StatusCode { - - /** - * Status code (100) indicating the client can continue. - */ - int SC_CONTINUE = 100; - - /** - * Status code (101) indicating the server is switching protocols according to Upgrade header. - */ - int SC_SWITCHING_PROTOCOLS = 101; - - /** - * Status code (200) indicating the request succeeded normally. - */ - int SC_OK = 200; - - /** - * Status code (201) indicating the request succeeded and created a new resource on the server. - */ - int SC_CREATED = 201; - - /** - * Status code (202) indicating that a request was accepted for processing, but was not completed. - */ - int SC_ACCEPTED = 202; - - /** - * Status code (203) indicating that the meta information presented by the client did not originate from the - * server. - */ - int SC_NON_AUTHORITATIVE_INFORMATION = 203; - - /** - * Status code (204) indicating that the request succeeded but that there was no new information to return. - */ - int SC_NO_CONTENT = 204; - - /** - * Status code (205) indicating that the agent SHOULD reset the document view which caused the request to - * be sent. - */ - int SC_RESET_CONTENT = 205; - - /** - * Status code (206) indicating that the server has fulfilled the partial GET request for the resource. - */ - int SC_PARTIAL_CONTENT = 206; - - /** - * Status code (300) indicating that the requested resource corresponds to any one of a set of representations, each - * with its own specific location. - */ - int SC_MULTIPLE_CHOICES = 300; - - /** - * Status code (301) indicating that the resource has permanently moved to a new location, and that future - * references should use a new URI with their requests. - */ - int SC_MOVED_PERMANENTLY = 301; - - /** - * Status code (302) indicating that the resource reside temporarily under a different URI. Since the redirection - * might be altered on occasion, the client should continue to use the Request-URI for future requests.(HTTP/1.1) To - * represent the status code (302), it is recommended to use this variable. - */ - int SC_FOUND = 302; - - /** - * Status code (303) indicating that the response to the request can be found under a different URI. - */ - int SC_SEE_OTHER = 303; - - /** - * Status code (304) indicating that a conditional GET operation found that the resource was available and not - * modified. - */ - int SC_NOT_MODIFIED = 304; - - /** - * Status code (305) indicating that the requested resource MUST be accessed through the proxy given by - * the - * Location field. - */ - int SC_USE_PROXY = 305; - - /** - * Status code (307) indicating that the requested resource resides temporarily under a different URI. The temporary - * URI - * SHOULD be given by the Location field in the response. - */ - int SC_TEMPORARY_REDIRECT = 307; - - /** - * Status code (400) indicating the request sent by the client was syntactically incorrect. - */ - int SC_BAD_REQUEST = 400; - - /** - * Status code (401) indicating that the request requires HTTP authentication. - */ - int SC_UNAUTHORIZED = 401; - - /** - * Status code (402) reserved for future use. - */ - int SC_PAYMENT_REQUIRED = 402; - - /** - * Status code (403) indicating the server understood the request but refused to fulfill it. - */ - int SC_FORBIDDEN = 403; - - /** - * Status code (404) indicating that the requested resource is not available. - */ - int SC_NOT_FOUND = 404; - - /** - * Status code (405) indicating that the method specified in the Request-Line is not allowed - * for the resource identified by the Request-URI. - */ - int SC_METHOD_NOT_ALLOWED = 405; - - /** - * Status code (406) indicating that the resource identified by the request is only capable of generating response - * entities which have content characteristics not acceptable according to the accept headers sent in the request. - */ - int SC_NOT_ACCEPTABLE = 406; - - /** - * Status code (407) indicating that the client MUST first authenticate itself with the proxy. - */ - int SC_PROXY_AUTHENTICATION_REQUIRED = 407; - - /** - * Status code (408) indicating that the client did not produce a request within the time that the server was - * prepared to wait. - */ - int SC_REQUEST_TIMEOUT = 408; - - /** - * Status code (409) indicating that the request could not be completed due to a conflict with the current state of - * the resource. - */ - int SC_CONFLICT = 409; - - /** - * Status code (410) indicating that the resource is no longer available at the server and no forwarding address is - * known. This condition SHOULD be considered permanent. - */ - int SC_GONE = 410; - - /** - * Status code (411) indicating that the request cannot be handled without a defined - * Content-Length. - */ - int SC_LENGTH_REQUIRED = 411; - - /** - * Status code (412) indicating that the precondition given in one or more of the request-header fields evaluated to - * false when it was tested on the server. - */ - int SC_PRECONDITION_FAILED = 412; - - /** - * Status code (413) indicating that the server is refusing to process the request because the request entity is - * larger than the server is willing or able to process. - */ - int SC_REQUEST_ENTITY_TOO_LARGE = 413; - - /** - * Status code (414) indicating that the server is refusing to service the request because the - * Request-URI is longer than the server is willing to interpret. - */ - int SC_REQUEST_URI_TOO_LONG = 414; - - /** - * Status code (415) indicating that the server is refusing to service the request because the entity of the request - * is in a format not supported by the requested resource for the requested method. - */ - int SC_UNSUPPORTED_MEDIA_TYPE = 415; - - /** - * Status code (416) indicating that the server cannot serve the requested byte range. - */ - int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - - /** - * Status code (417) indicating that the server could not meet the expectation given in the Expect request header. - */ - int SC_EXPECTATION_FAILED = 417; - - /** - * Status code (500) indicating an error inside the HTTP server which prevented it from fulfilling the request. - */ - int SC_INTERNAL_SERVER_ERROR = 500; - - /** - * Status code (501) indicating the HTTP server does not support the functionality needed to fulfill the request. - */ - int SC_NOT_IMPLEMENTED = 501; - - /** - * Status code (502) indicating that the HTTP server received an invalid response from a server it consulted when - * acting as a proxy or gateway. - */ - int SC_BAD_GATEWAY = 502; - - /** - * Status code (503) indicating that the HTTP server is temporarily overloaded, and unable to handle the request. - */ - int SC_SERVICE_UNAVAILABLE = 503; - - /** - * Status code (504) indicating that the server did not receive a timely response from the upstream server while - * acting as a gateway or proxy. - */ - int SC_GATEWAY_TIMEOUT = 504; - - /** - * Status code (505) indicating that the server does not support or refuses to support the HTTP protocol version - * that was used in the request message. - */ - int SC_HTTP_VERSION_NOT_SUPPORTED = 505; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/Uri.java b/api/src/main/java/com/yanzhenjie/andserver/http/Uri.java deleted file mode 100644 index df081667ea835103085b0b0bf810d661486c77d6..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/Uri.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.http; - - -import com.yanzhenjie.andserver.util.*; -import org.apache.commons.io.Charsets; - -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.*; - -/** - * Add the mPath to the URL, such as: - *

- * Uri url = Uri.newBuilder("http://www.example.com/xx")
- *      .scheme("https")
- *      .port(8080)
- *      .path("yy")
- *      .query("abc", "123")
- *      .setFragment("article")
- *      .build();
- * ...
- * The real url is: https://www.example.com:8080/xx/yy?abc=123#article.
- * 
- *
- * Uri url = Uri.newBuilder("http://www.example.com/xx/yy?abc=123")
- *      .setSegments("/aa/bb/cc")
- *      .setQuery("mln=456&ijk=789")
- *      .build();
- * ...
- * The real url is: http://www.example.com/aa/bb/cc?mln=456&ijk=789.
- * 
- *
- * Uri url = Uri.newBuilder("http://www.example.com/user/photo/search?name=abc").build();
- * Uri newUrl = url.location("../../get?name=mln");
- * ...
- * The new url is: http://www.example.com/get?name=abc.
- * 
- * Created by Zhenjie Yan on 2018/2/9. - */ -public class Uri implements Patterns { - - public static Builder newBuilder(String uri) { - return new Builder(uri); - } - - private final String mScheme; - private final String mHost; - private final int mPort; - private final String mPath; - private final String mQuery; - private final String mFragment; - - private Uri(Builder builder) { - this.mScheme = builder.mScheme; - this.mHost = builder.mHost; - this.mPort = builder.mPort; - this.mPath = pathsToPath(builder.mPath); - this.mQuery = parametersToQuery(builder.mQuery); - this.mFragment = builder.mFragment; - } - - - public String getScheme() { - return mScheme; - } - - - public String getHost() { - return mHost; - } - - public int getPort() { - return mPort; - } - - - public String getPath() { - return mPath; - } - - - public List getPaths() { - return pathToPaths(mPath); - } - - - public String getQuery() { - return mQuery; - } - - - public MultiValueMap getParams() { - return queryToParameters(mQuery); - } - - - public String getFragment() { - return mFragment; - } - - - public Builder builder() { - return new Builder(toString()); - } - - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - if (StringUtils.isEmpty(mScheme)) { - builder.append(mScheme).append(":"); - } - - if (!StringUtils.isEmpty(mHost) && mPort > 0) { - builder.append("//").append(mHost).append(":").append(mPort); - } - - if (!StringUtils.isEmpty(mPath)) { - builder.append(mPath); - } - - if (!StringUtils.isEmpty(mQuery)) { - builder.append("?").append(mQuery); - } - - if (!StringUtils.isEmpty(mFragment)) { - builder.append("#").append(mFragment); - } - - return builder.toString(); - } - - - public Uri location(String location) { - if (StringUtils.isEmpty(location)) { - return null; - } - - if (URLUtil.isNetworkUrl(location)) { - return newBuilder(location).build(); - } - - URI newUri = URI.create(location); - if (location.startsWith("/")) { - return builder().setPath(newUri.getPath()) - .setQuery(newUri.getQuery()) - .setFragment(newUri.getFragment()) - .build(); - } else if (location.contains("../")) { - List oldPathList = pathToPaths(getPath()); - List newPathList = pathToPaths(newUri.getPath()); - - int start = newPathList.lastIndexOf(".."); - newPathList = newPathList.subList(start + 1, newPathList.size()); - if (!oldPathList.isEmpty()) { - oldPathList = oldPathList.subList(0, oldPathList.size() - start - 2); - oldPathList.addAll(newPathList); - String path = TextUtils.join("/", oldPathList); - return builder().setPath(path).setQuery(newUri.getQuery()).setFragment(newUri.getFragment()).build(); - } - String path = TextUtils.join("/", newPathList); - return builder().setPath(path).setQuery(newUri.getQuery()).setFragment(newUri.getFragment()).build(); - } else { - List oldPathList = pathToPaths(getPath()); - oldPathList.addAll(pathToPaths(newUri.getPath())); - String path = TextUtils.join("/", oldPathList); - return builder().setPath(path).setQuery(newUri.getQuery()).setFragment(newUri.getFragment()).build(); - } - } - - public static class Builder { - - private String mScheme; - private String mHost; - private int mPort; - private List mPath; - private MultiValueMap mQuery; - private String mFragment; - - private Builder( String url) { - URI uri = URI.create(url); - - this.mScheme = uri.getScheme(); - this.mHost = uri.getHost(); - this.mPort = uri.getPort(); - String path = uri.getPath(); - this.mPath = pathToPaths(path); - String query = uri.getQuery(); - this.mQuery = queryToParameters(query); - this.mFragment = uri.getFragment(); - } - - public Builder setScheme( String scheme) { - this.mScheme = scheme; - return this; - } - - public Builder setHost( String host) { - this.mHost = host; - return this; - } - - public Builder setPort(int port) { - this.mPort = port; - return this; - } - - public Builder addPath(int value) { - return addPath(Integer.toString(value)); - } - - public Builder addPath(long value) { - return addPath(Long.toString(value)); - } - - public Builder addPath(boolean value) { - return addPath(Boolean.toString(value)); - } - - public Builder addPath(char value) { - return addPath(String.valueOf(value)); - } - - public Builder addPath(double value) { - return addPath(Double.toString(value)); - } - - public Builder addPath(float value) { - return addPath(Float.toString(value)); - } - - public Builder addPath( CharSequence path) { - mPath.add(path.toString()); - return this; - } - - public Builder addPath( String path) { - mPath.add(path); - return this; - } - - public Builder setPath( String path) { - mPath = pathToPaths(path); - return this; - } - - public Builder clearPath() { - mPath.clear(); - return this; - } - - public Builder addQuery( String key, int value) { - return addQuery(key, Integer.toString(value)); - } - - public Builder addQuery( String key, long value) { - return addQuery(key, Long.toString(value)); - } - - public Builder addQuery( String key, boolean value) { - return addQuery(key, Boolean.toString(value)); - } - - public Builder addQuery( String key, char value) { - return addQuery(key, String.valueOf(value)); - } - - public Builder addQuery( String key, double value) { - return addQuery(key, Double.toString(value)); - } - - public Builder addQuery( String key, float value) { - return addQuery(key, Float.toString(value)); - } - - public Builder addQuery( String key, short value) { - return addQuery(key, Integer.toString(value)); - } - - public Builder addQuery( String key, CharSequence value) { - mQuery.add(key, value.toString()); - return this; - } - - public Builder addQuery( String key, String value) { - mQuery.add(key, value); - return this; - } - - public Builder addQuery( String key, List values) { - for (String value: values) { - mQuery.add(key, value); - } - return this; - } - - public Builder setQuery( String query) { - mQuery = queryToParameters(query); - return this; - } - - public Builder setQuery( MultiValueMap query) { - mQuery = query; - return this; - } - - public Builder removeQuery( String key) { - mQuery.remove(key); - return this; - } - - public Builder clearQuery() { - mQuery.clear(); - return this; - } - - public Builder setFragment( String fragment) { - this.mFragment = fragment; - return this; - } - - public Uri build() { - return new Uri(this); - } - } - - public static List pathToPaths(String path) { - List pathList = new LinkedList<>(); - if (StringUtils.isEmpty(path)) { - return pathList; - } - - while (path.contains("//")) { - path = path.replace("//", "/"); - } - - while (path.contains("/")) { - if (path.startsWith("/")) { - pathList.add(""); - path = path.substring(1); - } else { - int index = path.indexOf("/"); - pathList.add(path.substring(0, index)); - path = path.substring(index + 1); - } - - if (!path.contains("/")) { - pathList.add(path); - } - } - return pathList; - } - - public static MultiValueMap queryToParameters(String query) { - MultiValueMap valueMap = new LinkedMultiValueMap<>(); - if (!StringUtils.isEmpty(query)) { - if (query.startsWith("?")) { - query = query.substring(1); - } - - StringTokenizer tokenizer = new StringTokenizer(query, "&"); - while (tokenizer.hasMoreElements()) { - String element = tokenizer.nextToken(); - int end = element.indexOf("="); - - if (end > 0 && end < element.length() - 1) { - String key = element.substring(0, end); - String value = element.substring(end + 1); - valueMap.add(key, UrlCoder.urlDecode(value, StandardCharsets.UTF_8)); - } - } - } - return valueMap; - } - - public static String pathsToPath(List pathList) { - if (pathList == null || pathList.isEmpty()) { - return ""; - } - - StringBuilder builder = new StringBuilder(); - for (String path: pathList) { - builder.append("/").append(path); - } - - String path = builder.toString(); - while (path.contains("//")) { - path = path.replace("//", "/"); - } - return path; - } - - public static String parametersToQuery(MultiValueMap params) { - StringBuilder builder = new StringBuilder(); - Iterator>> iterator = params.entrySet().iterator(); - if (iterator.hasNext()) { - Map.Entry> param = iterator.next(); - String key = param.getKey(); - List valueList = param.getValue(); - if (valueList != null && !valueList.isEmpty()) { - for (String value: valueList) { - builder.append(key).append("=").append(value); - } - } else { - builder.append(key).append("="); - } - } - - while (iterator.hasNext()) { - Map.Entry> param = iterator.next(); - String key = param.getKey(); - List valueList = param.getValue(); - if (valueList != null && !valueList.isEmpty()) { - for (String value: valueList) { - builder.append("&").append(key).append("=").append(value); - } - } else { - builder.append("&").append(key).append("="); - } - } - return builder.toString(); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/Cookie.java b/api/src/main/java/com/yanzhenjie/andserver/http/cookie/Cookie.java deleted file mode 100644 index 86dfcb9edfcffa159668aff90fb235c00f4d3f45..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/Cookie.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.cookie; - -import com.yanzhenjie.andserver.util.StringUtils; - -import java.io.Serializable; -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018 - */ -public class Cookie implements Cloneable, Serializable { - - private static final String TSPECIALS = "/()<>@,;:\\\"[]?={} \t"; - - private String name; // NAME= ... "$Name" style is reserved. - private String value; // value of NAME. - - private String comment; // ;Comment=VALUE ... describes cookie's use. - // ;Discard ... implied by maxAge < 0 - private String domain; // ;Domain=VALUE ... domain that sees cookie. - private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire. - private String path; // ;Path=VALUE ... URLs that see the cookie. - private boolean secure; // ;Secure ... e.g. use SSL. - private int version = 0; // ;Version=1 ... means RFC 2109++ style. - private boolean isHttpOnly = false; - - /** - * Constructs a cookie with the specified name and value. - * - *

The name must conform to RFC 2109. - * - *

The name of a cookie cannot be changed once the cookie has been created. - * - *

The value can be anything the server chooses to send. Its value is probably of interest only to the server. - * The cookie's value can be changed after creation with the {@link #setValue(String)} method. - * - *

The version can be changed with the {@link #setVersion(int)} method. - * - * @param name the name of the cookie. - * @param value the value of the cookie. - * - * @throws IllegalArgumentException if the cookie name is null or empty or contains any illegal characters (e.g. - * a comma, space, or semicolon) or matches a token reserved for use by the cookie protocol. - * @see #setValue(String) - * @see #setVersion(int) - */ - public Cookie( String name, String value) { - if (StringUtils.isEmpty(name)) { - throw new IllegalArgumentException("The name of the cookie cannot be empty or null."); - } - if (!isToken(name) || name.equalsIgnoreCase("Comment") || // rfc2019 - name.equalsIgnoreCase("Discard") || // 2019++ - name.equalsIgnoreCase("Domain") || name.equalsIgnoreCase("Expires") || // (old cookies) - name.equalsIgnoreCase("Max-Age") || // rfc2019 - name.equalsIgnoreCase("Path") || name.equalsIgnoreCase("Secure") || name.equalsIgnoreCase("Version") || - name.startsWith("$")) { - String message = String.format("This name [%1$s] is a reserved character.", name); - throw new IllegalArgumentException(message); - } - - this.name = name; - this.value = value; - } - - /** - * Specifies a comment that describes a cookie's purpose. The comment is useful if the browser presents the cookie - * to the user. - * - * @param purpose a {@link String} specifying the comment to display to the user. - * - * @see #getComment() - */ - public void setComment(String purpose) { - comment = purpose; - } - - /** - * Returns the comment describing the purpose of this cookie, or {@code null} if the cookie has no comment. - * - * @return the comment of the cookie, or {@code null} if unspecified. - * - * @see #setComment(String) - */ - - public String getComment() { - return comment; - } - - /** - * Specifies the domain within which this cookie should be presented. - * - *

The form of the domain name is specified by RFC 2109. StandardCookieProcessor domain name begins with a dot - * ({@code .foo.com}) and means that the cookie is visible to servers in a specified Domain Name System (DNS) zone - * (e.g. {@code www.foo.com}, but not {@code a.b.foo.com}). By default, cookies are only returned to the server that - * sent them. - * - * @param domain the domain name within which this cookie is visible; form is according to RFC 2109. - * - * @see #getDomain() - */ - public void setDomain(String domain) { - if (!StringUtils.isEmpty(domain)) { - this.domain = domain.toLowerCase(Locale.ENGLISH); // IE allegedly needs this. - } else { - this.domain = null; - } - } - - /** - * Gets the domain name of this Cookie. - * - *

Domain names are formatted according to RFC 2109. - * - * @return the domain name of this Cookie. - * - * @see #setDomain(String) - */ - - public String getDomain() { - return domain; - } - - /** - * Sets the maximum age in seconds for this Cookie. - * - *

StandardCookieProcessor positive value indicates that the cookie will expire after that many seconds have - * passed. Note that the value is the maximum age when the cookie will expire, not the cookie's current age. - * - *

StandardCookieProcessor negative value means that the cookie is not stored persistently and will be deleted - * when the Web browser exits. StandardCookieProcessor zero value causes the cookie to be deleted. - * - * @param expiry an integer specifying the maximum age of the cookie in seconds; if negative, means the cookie - * is not stored; if zero, deletes the cookie. - * - * @see #getMaxAge() - */ - public void setMaxAge(int expiry) { - maxAge = expiry; - } - - /** - * Gets the maximum age in seconds of this Cookie. - * - *

By default, {@code -1} is returned, which indicates that the cookie will persist until browser shutdown. - * - * @see #setMaxAge(int) - */ - public int getMaxAge() { - return maxAge; - } - - /** - * Specifies a path for the cookie to which the client should return the cookie. - * - *

The cookie is visible to all the pages in the directory you specify, and all the pages in that directory's - * subdirectories. - * - *

Consult RFC 2109 (available on the Internet) for more information on setting path names for cookies. - * - * @param path a {@code String} specifying a path. - * - * @see #getPath() - */ - public void setPath(String path) { - this.path = path; - } - - /** - * Returns the path on the server to which the browser returns this cookie. The cookie is visible to all subpaths on - * the server. - * - * @see #setPath(String) - */ - - public String getPath() { - return path; - } - - /** - * Indicates to the browser whether the cookie should only be sent using a secure protocol, e.g. HTTPS or SSL. - * - *

The default value is {@code false}. - * - * @param flag if {@code true}, sends the cookie from the browser to the server only when using a secure - * protocol; if {@code false}, sent on any protocol. - * - * @see #getSecure() - */ - public void setSecure(boolean flag) { - secure = flag; - } - - /** - * Returns {@code true} if the browser is sending cookies only over a secure protocol, or {@code false} if the - * browser can send cookies using any protocol. - * - * @return {@code true} if the browser uses a secure protocol, {@code false} otherwise. - * - * @see #setSecure(boolean) - */ - public boolean getSecure() { - return secure; - } - - /** - * Returns the name of the cookie. The name cannot be changed after creation. - * - * @return the name of the cookie. - */ - - public String getName() { - return name; - } - - /** - * Assigns a new value to this Cookie. - * - *

If you use a binary value, you may want to use BASE64 encoding. - * - *

With Version 0 cookies, values should not contain white space, brackets, parentheses, equals signs, commas, - * double quotes, slashes, question marks, at signs, colons, and semicolons. Empty values may not behave the same - * way on all browsers. - * - * @param newValue the new value of the cookie. - * - * @see #getValue() - */ - public void setValue(String newValue) { - value = newValue; - } - - /** - * Gets the current value of this Cookie. - * - * @return the current value of this Cookie. - * - * @see #setValue(String) - */ - - public String getValue() { - return value; - } - - /** - * Returns the version of the protocol this cookie complies with. Version 1 complies with RFC 2109, and version 0 - * complies with the original cookie specification drafted by Netscape. Cookies provided by a browser use and - * identify the browser's cookie version. - * - * @see #setVersion(int) - */ - public int getVersion() { - return version; - } - - /** - * Sets the version of the cookie protocol that this Cookie complies with. - * - *

Version 0 complies with the original Netscape cookie specification. Version 1 complies with RFC 2109. - * - *

Since RFC 2109 is still somewhat new, consider version 1 as experimental; do not use it yet on production - * sites. - * - * @param v 0 if the cookie should comply with the original Netscape specification; 1 if the cookie should - * comply with RFC 2109. - * - * @see #getVersion() - */ - public void setVersion(int v) { - version = v; - } - - /** - * Tests a string and returns true if the string counts as a reserved token in the Java language. - * - * @param value the {@code String} to be tested. - * - * @return {@code true} if the {@code String} is a reserved token; {@code false} otherwise. - */ - private boolean isToken(String value) { - int len = value.length(); - for (int i = 0; i < len; i++) { - char c = value.charAt(i); - if (c < 0x20 || c >= 0x7f || TSPECIALS.indexOf(c) != -1) { - return false; - } - } - - return true; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e.getMessage()); - } - } - - /** - * Marks or unmarks this Cookie as HttpOnly. - * - *

If isHttpOnly is set to true, this cookie is marked as HttpOnly, by adding the - * HttpOnly attribute to it. - * - *

HttpOnly cookies are not supposed to be exposed to client-side scripting code, and may therefore help - * mitigate certain kinds of cross-site scripting attacks. - * - * @param isHttpOnly true if this cookie is to be marked as HttpOnly, false otherwise. - */ - public void setHttpOnly(boolean isHttpOnly) { - this.isHttpOnly = isHttpOnly; - } - - /** - * Checks whether this Cookie has been marked as HttpOnly. - * - * @return true if this Cookie has been marked as HttpOnly, false otherwise. - */ - public boolean isHttpOnly() { - return isHttpOnly; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/CookieProcessor.java b/api/src/main/java/com/yanzhenjie/andserver/http/cookie/CookieProcessor.java deleted file mode 100644 index 0c30bad639a8d79794002fc691726b232133c0be..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/CookieProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.cookie; - - - - -import org.apache.httpcore.Header; - -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/7/27. - */ -public interface CookieProcessor { - - /** - * Parse the provided headers into server cookie objects. - * - * @param headers the HTTP headers to parse. - */ - - List parseCookieHeader(Header[] headers); - - /** - * Generate the {@code Set-Cookie} HTTP header value for the given {@code Cookie}. - * - * @param cookie the cookie for which the header will be generated. - * - * @return the header value in a form that can be added directly to the response. - */ - - String generateHeader(Cookie cookie); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/StandardCookieProcessor.java b/api/src/main/java/com/yanzhenjie/andserver/http/cookie/StandardCookieProcessor.java deleted file mode 100644 index 7d5616c97661f4ccc74a7acfce48083dd17c6aa0..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/cookie/StandardCookieProcessor.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.cookie; - -import com.yanzhenjie.andserver.util.StringUtils; -import org.apache.httpcore.Header; - -import java.text.DateFormat; -import java.text.FieldPosition; -import java.text.SimpleDateFormat; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/7/27. - */ -public class StandardCookieProcessor implements CookieProcessor { - - private static final String COOKIE_DATE_PATTERN = "EEE, dd-MMM-yyyy HH:mm:ss z"; - - private static final ThreadLocal COOKIE_DATE_FORMAT = new ThreadLocal() { - @Override - protected DateFormat initialValue() { - DateFormat df = new SimpleDateFormat(COOKIE_DATE_PATTERN, Locale.US); - df.setTimeZone(TimeZone.getTimeZone("GMT")); - return df; - } - }; - - private static final String ANCIENT_DATE = COOKIE_DATE_FORMAT.get().format(new Date(10000)); - private static final BitSet DOMAIN_VALID = new BitSet(128); - - static { - for (char c = '0'; c <= '9'; c++) { - DOMAIN_VALID.set(c); - } - for (char c = 'a'; c <= 'z'; c++) { - DOMAIN_VALID.set(c); - } - for (char c = 'A'; c <= 'Z'; c++) { - DOMAIN_VALID.set(c); - } - DOMAIN_VALID.set('.'); - DOMAIN_VALID.set('-'); - } - - - @Override - public List parseCookieHeader(Header[] headers) { - if (headers == null || headers.length == 0) { - return Collections.emptyList(); - } - - List cookieList = new ArrayList<>(); - for (Header header: headers) { - String name = header.getName(); - if ("Cookie".equalsIgnoreCase(name)) { - String headerValue = header.getValue(); - parserCookieValue(headerValue, cookieList); - } - } - return cookieList; - } - - private void parserCookieValue(String headerValue, List cookieList) { - StringTokenizer tokenizer = new StringTokenizer(headerValue, ";"); - while (tokenizer.hasMoreTokens()) { - String segment = tokenizer.nextToken(); - int split = segment.indexOf("="); - int valueIndex = split + 1; - if (split > 0 && valueIndex < segment.length()) { - String name = segment.substring(0, split).trim(); - String value = segment.substring(valueIndex, segment.length()).trim(); - cookieList.add(new Cookie(name, value)); - } - } - } - - - @Override - public String generateHeader( Cookie cookie) { - // Can't use StringBuilder due to DateFormat. - StringBuffer header = new StringBuffer(); - header.append(cookie.getName()); - header.append('='); - String value = cookie.getValue(); - if (!StringUtils.isEmpty(value)) { - validateCookieValue(value); - header.append(value); - } - - // RFC 6265 prefers Max-Age to Expires but... (see below). - int maxAge = cookie.getMaxAge(); - if (maxAge > -1) { - // Negative Max-Age is equivalent to no Max-Age. - header.append("; Max-Age="); - header.append(maxAge); - - // Microsoft IE and Microsoft Edge don't understand Max-Age so send - // expires as well. Without this, persistent cookies fail with those - // browsers. See http://tomcat.markmail.org/thread/g6sipbofsjossacn. - - // Wdy, DD-Mon-YY HH:MM:SS GMT (Expires Netscape format). - header.append("; Expires="); - // To expire immediately we need to set the time in past. - if (maxAge == 0) { - header.append(ANCIENT_DATE); - } else { - Date date = new Date(System.currentTimeMillis() + maxAge * 1000L); - COOKIE_DATE_FORMAT.get().format(date, header, new FieldPosition(0)); - } - } - - String domain = cookie.getDomain(); - if (domain != null && domain.length() > 0) { - validateDomain(domain); - header.append("; Domain="); - header.append(domain); - } - - String path = cookie.getPath(); - if (path != null && path.length() > 0) { - validatePath(path); - header.append("; Path="); - header.append(path); - } - - if (cookie.getSecure()) { - header.append("; Secure"); - } - - if (cookie.isHttpOnly()) { - header.append("; HttpOnly"); - } - - return header.toString(); - } - - - private void validateCookieValue(String value) { - int start = 0; - int end = value.length(); - - if (end > 1 && value.charAt(0) == '"' && value.charAt(end - 1) == '"') { - start = 1; - end--; - } - - char[] chars = value.toCharArray(); - for (int i = start; i < end; i++) { - char c = chars[i]; - if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) { - String message = String.format("The cookie's value [%1$s] is invalid.", value); - throw new IllegalArgumentException(message); - } - } - } - - - private void validateDomain(String domain) { - int i = 0; - int prev = -1; - int cur = -1; - char[] chars = domain.toCharArray(); - while (i < chars.length) { - prev = cur; - cur = chars[i]; - if (!DOMAIN_VALID.get(cur)) { - String message = String.format("The cookie's domain [%1$s] is invalid.", domain); - throw new IllegalArgumentException(message); - } - // labels must start with a letter or number. - if ((prev == '.' || prev == -1) && (cur == '.' || cur == '-')) { - String message = String.format("The cookie's domain [%1$s] is invalid.", domain); - throw new IllegalArgumentException(message); - } - // labels must end with a letter or number. - if (prev == '-' && cur == '.') { - String message = String.format("The cookie's domain [%1$s] is invalid.", domain); - throw new IllegalArgumentException(message); - } - i++; - } - // domain must end with a label. - if (cur == '.' || cur == '-') { - String message = String.format("The cookie's domain [%1$s] is invalid.", domain); - throw new IllegalArgumentException(message); - } - } - - - private void validatePath(String path) { - char[] chars = path.toCharArray(); - - for (int i = 0; i < chars.length; i++) { - char ch = chars[i]; - if (ch < 0x20 || ch > 0x7E || ch == ';') { - String message = String.format("The cookie's path [%1$s] is invalid.", path); - throw new IllegalArgumentException(message); - } - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/BodyContext.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/BodyContext.java deleted file mode 100644 index 39867610049d82e32de6f0eb2bdbcc07e64a256c..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/BodyContext.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - - - -import com.yanzhenjie.andserver.http.RequestBody; -import com.yanzhenjie.andserver.util.MediaType; -import org.apache.commons.fileupload.UploadContext; - -import java.io.IOException; -import java.io.InputStream; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public class BodyContext implements UploadContext { - - private final RequestBody mBody; - - public BodyContext( RequestBody body) { - this.mBody = body; - } - - @Override - public String getCharacterEncoding() { - return mBody.contentEncoding(); - } - - @Override - public String getContentType() { - MediaType contentType = mBody.contentType(); - return contentType == null ? null : contentType.toString(); - } - - @Override - public int getContentLength() { - long contentLength = contentLength(); - return contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) contentLength; - } - - @Override - public long contentLength() { - return mBody.length(); - } - - @Override - public InputStream getInputStream() throws IOException { - return mBody.stream(); - } - - @Override - public String toString() { - return String.format("ContentLength=%s, Mime=%s", contentLength(), getContentType()); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartFile.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartFile.java deleted file mode 100644 index 8868aba43fecd4d4f110533c5f467d86ee07d218..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartFile.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - - -import com.yanzhenjie.andserver.util.MediaType; -import org.apache.commons.fileupload.FileItem; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -/** - * Created by Zhenjie Yan on 2018/6/18. - */ -public interface MultipartFile { - - /** - * Return the name of the parameter in the multipart form. - * - * @return the name of the parameter. - */ - - String getName(); - - /** - * Return the original filename in the client's filesystem. - * - * @return the original filename, or the empty String if no file, or null if not defined. - * - * @see FileItem#getName() - */ - - String getFilename(); - - /** - * Return the content type of the file. - * - * @return the content type, or the empty String if no file, or null if not defined. - */ - - MediaType getContentType(); - - /** - * Return whether the uploaded file is empty. - * - * @return true, otherwise is false. - */ - boolean isEmpty(); - - /** - * Return the size of the file in bytes. - * - * @return the size of the file, or 0 if empty. - */ - long getSize(); - - /** - * Return the contents of the file as an array of bytes. - * - * @return the contents of the file as bytes, or an empty byte array if empty. - * - * @throws IOException in case of access errors (if the temporary store fails). - */ - byte[] getBytes() throws IOException; - - /** - * Return an {@code InputStream} to read the contents of the file from. - * - * @return the contents of the file as stream, or an empty stream if empty. - * - * @throws IOException in case of access errors. - */ - - InputStream getStream() throws IOException; - - /** - * Writing the received file to the given destination file. If the destination file already exists, it will be - * deleted first. - * - *

If the target file has been written to disk, this operation cannot be invoked again afterwards. - * - * @param dest the destination file. - */ - void transferTo(File dest) throws IOException, IllegalStateException; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartRequest.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartRequest.java deleted file mode 100644 index f80b4bdfe7621d8dd10d4d49ddb9ff442c7331ef..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartRequest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.util.MultiValueMap; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -/** - *

This interface defines the multipart request access operations that are exposed for actual multipart requests. - *

- * - * Created by Zhenjie Yan on 2018/6/21. - */ -public interface MultipartRequest extends HttpRequest { - - /** - *

Return an {@link Iterator} of String objects containing the parameter names of the multipart files - * contained in this request. These are the field names of the form (like with normal parameters), not the original - * file names.

- * - * @return the names of the files. - */ - - Iterator getFileNames(); - - /** - * Return the contents plus description of an uploaded file in this request, or null if it does not exist. - * - * @param name parameter name. - * - * @return a {@link MultipartFile} object. - */ - - MultipartFile getFile(String name); - - /** - * Return the contents plus description of uploaded files in this request, or an empty list if it does not exist. - * - * @param name parameter name. - * - * @return a {@link MultipartFile} list. - */ - - List getFiles(String name); - - /** - * Return a {@link Map} of the multipart files contained in this request. - * - * @return a map containing the parameter names as keys, and the {@link MultipartFile} objects as values. - */ - - Map getFileMap(); - - /** - * Return a {@link MultiValueMap} of the multipart files contained in this request. - * - * @return a map containing the parameter names as keys, and a list of {@link MultipartFile} objects as values. - */ - - MultiValueMap getMultiFileMap(); - - /** - * Determine the content type of the specified request part. - * - * @param paramOrFileName the name of the part. - * - * @return the associated content type, or null if not defined. - */ - - String getMultipartContentType(String paramOrFileName); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartResolver.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartResolver.java deleted file mode 100644 index ef49fd49c7825a58dddc6bf9f9efac5685b868ff..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/MultipartResolver.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - -import com.yanzhenjie.andserver.error.MultipartException; -import com.yanzhenjie.andserver.http.HttpRequest; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; - -import java.io.File; - -/** - * Created by Zhenjie Yan on 2018/8/8. - */ -public interface MultipartResolver { - - /** - * Set the maximum size (in bytes) allowed for uploading. -1 indicates no limit (the default). - * - * @param allFileMaxSize the maximum upload size allowed. - * - * @see FileUpload#setSizeMax(long) - */ - void setAllFileMaxSize(long allFileMaxSize); - - /** - * Set the maximum size (in bytes) allowed for each individual file. -1 indicates no limit (the default). - * - * @param fileMaxSize the maximum upload size per file. - * - * @see FileUpload#setFileSizeMax(long) - */ - void setFileMaxSize(long fileMaxSize); - - /** - * Set the maximum allowed size (in bytes) before uploads are written to disk, default is 10240. - * - * @param maxInMemorySize the maximum in memory size allowed. - * - * @see DiskFileItemFactory#setSizeThreshold(int) - */ - void setMaxInMemorySize(int maxInMemorySize); - - /** - * Set the temporary directory where uploaded files get stored. - */ - void setUploadTempDir(File uploadTempDir); - - /** - * Determine if the given request contains multipart content, will typically check for content type - * "multipart/form-data". - * - * @param request the request to be evaluated. - * - * @return whether the request contains multipart content. - */ - boolean isMultipart(HttpRequest request); - - /** - * Parse the given request into multipart files and parameters, and wrap the request inside a {@link - * MultipartRequest} object that provides access to file descriptors and makes contained parameters accessible via - * the standard HttpRequest methods. - * - * @param request the request to wrap (must be of a multipart content type). - * - * @return the wrapped request. - * - * @throws MultipartException if the request is not multipart, or encounter other problems. - */ - MultipartRequest resolveMultipart(HttpRequest request) throws MultipartException; - - /** - * Cleanup any resources used for the multipart handling, like a storage for the uploaded files. - * - * @param request the request to cleanup resources for. - */ - void cleanupMultipart(MultipartRequest request); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartFile.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartFile.java deleted file mode 100644 index ac55895ae0f7c36879a6a2e7b4b243fb558023b7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartFile.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - -import com.yanzhenjie.andserver.util.IOUtils; -import com.yanzhenjie.andserver.util.MediaType; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.disk.DiskFileItem; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; - -/** - * Created by Zhenjie Yan on 2018/6/21. - */ -public class StandardMultipartFile implements MultipartFile, Serializable { - - private final FileItem fileItem; - private final long size; - - /** - * Create an instance wrapping the given FileItem. - * - * @param fileItem the FileItem to wrap. - */ - public StandardMultipartFile(FileItem fileItem) { - this.fileItem = fileItem; - this.size = fileItem.getSize(); - } - - /** - * Return the underlying {@link FileItem} instance. There is hardly any need to access this. - */ - public final FileItem getFileItem() { - return fileItem; - } - - - @Override - public String getName() { - return this.fileItem.getFieldName(); - } - - - @Override - public String getFilename() { - String filename = this.fileItem.getName(); - if (filename == null) { - // Should never happen. - return ""; - } - - // Check for Unix-style path. - int unixSep = filename.lastIndexOf("/"); - // Check for Windows-style path. - int winSep = filename.lastIndexOf("\\"); - // Cut off at latest possible point. - int pos = (winSep > unixSep ? winSep : unixSep); - if (pos != -1) { - // Any sort of path separator found... - return filename.substring(pos + 1); - } else { - // A plain name. - return filename; - } - } - - - @Override - public MediaType getContentType() { - String mimeType = fileItem.getContentType(); - MediaType mediaType; - try { - mediaType = MediaType.parseMediaType(mimeType); - } catch (Exception e) { - mediaType = MediaType.APPLICATION_OCTET_STREAM; - } - return mediaType; - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - @Override - public long getSize() { - return size; - } - - @Override - public byte[] getBytes() { - if (!isAvailable()) { - throw new IllegalStateException("File has been moved - cannot be read again."); - } - byte[] bytes = this.fileItem.get(); - return (bytes != null ? bytes : new byte[0]); - } - - - @Override - public InputStream getStream() throws IOException { - if (!isAvailable()) { - throw new IllegalStateException("File has been moved - cannot be read again."); - } - InputStream inputStream = fileItem.getInputStream(); - return (inputStream != null ? inputStream : IOUtils.createEmptyInput()); - } - - @Override - public void transferTo( File dest) throws IOException, IllegalStateException { - if (!isAvailable()) { - throw new IllegalStateException("File has already been moved - cannot be transferred again."); - } - - if (dest.exists() && !dest.delete()) { - throw new IOException( - "Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted."); - } - - try { - fileItem.write(dest); - } catch (FileUploadException ex) { - throw new IllegalStateException(ex.getMessage(), ex); - } catch (IllegalStateException ex) { - // Pass through when coming from FileItem directly. - throw ex; - } catch (IOException ex) { - // From I/O operations within FileItem.write. - throw ex; - } catch (Exception ex) { - throw new IOException("File transfer failed", ex); - } - } - - /** - * Determine whether the multipart content is still available. If a temporary file has been moved, the content is no - * longer available. - */ - protected boolean isAvailable() { - // If in memory, it's available. - if (fileItem.isInMemory()) { - return true; - } - // Check actual existence of temporary file. - if (fileItem instanceof DiskFileItem) { - return ((DiskFileItem) fileItem).getStoreLocation().exists(); - } - // Check whether current file size is different than original one. - return (fileItem.getSize() == size); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartRequest.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartRequest.java deleted file mode 100644 index 783d0da5eb1e119d2c75249c68da5189e6381303..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartRequest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - - -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.RequestWrapper; -import com.yanzhenjie.andserver.util.LinkedMultiValueMap; -import com.yanzhenjie.andserver.util.MultiValueMap; - -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public class StandardMultipartRequest extends RequestWrapper implements MultipartRequest { - - private HttpRequest mRequest; - - private MultiValueMap mMultipartFiles; - private MultiValueMap mMultipartParameters; - private Map mMultipartContentTypes; - - public StandardMultipartRequest( HttpRequest request, MultiValueMap mpFiles, - MultiValueMap mpParams, - Map mpContentTypes) { - super(request); - this.mRequest = request; - this.mMultipartFiles = new LinkedMultiValueMap<>(Collections.unmodifiableMap(mpFiles)); - this.mMultipartParameters = new LinkedMultiValueMap<>(Collections.unmodifiableMap(mpParams)); - this.mMultipartContentTypes = Collections.unmodifiableMap(mpContentTypes); - } - - - @Override - public Iterator getFileNames() { - return mMultipartFiles.keySet().iterator(); - } - - - @Override - public MultipartFile getFile(String name) { - return mMultipartFiles.getFirst(name); - } - - - @Override - public List getFiles(String name) { - List multipartFiles = mMultipartFiles.get(name); - if (multipartFiles != null) { - return multipartFiles; - } else { - return Collections.emptyList(); - } - } - - - @Override - public Map getFileMap() { - return mMultipartFiles.toSingleValueMap(); - } - - - @Override - public MultiValueMap getMultiFileMap() { - return mMultipartFiles; - } - - - @Override - public String getMultipartContentType(String paramOrFileName) { - MultipartFile file = getFile(paramOrFileName); - return file == null ? mMultipartContentTypes.get(paramOrFileName) : file.getContentType().getType(); - } - - - @Override - public List getParameterNames() { - if (mMultipartParameters.isEmpty()) { - return mRequest.getParameterNames(); - } - - List paramNames = new LinkedList<>(); - List names = mRequest.getParameterNames(); - if (!names.isEmpty()) { - paramNames.addAll(names); - } - paramNames.addAll(mMultipartParameters.keySet()); - return paramNames; - } - - - @Override - public String getParameter( String name) { - String value = mMultipartParameters.getFirst(name); - return value.isEmpty() ? mRequest.getParameter(name) : value; - } - - - @Override - public List getParameters( String name) { - List values = mMultipartParameters.get(name); - return values == null ? mRequest.getParameters(name) : values; - } - - - @Override - public MultiValueMap getParameter() { - return mMultipartParameters.isEmpty() ? mRequest.getParameter() : mMultipartParameters; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartResolver.java b/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartResolver.java deleted file mode 100644 index 2f9fd100aa0d458d9e31fa2d4554f580335e691b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/multipart/StandardMultipartResolver.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.multipart; - -import com.yanzhenjie.andserver.AndServer; -import com.yanzhenjie.andserver.error.MaxUploadSizeExceededException; -import com.yanzhenjie.andserver.error.MultipartException; -import com.yanzhenjie.andserver.http.HttpRequest; -import com.yanzhenjie.andserver.http.RequestBody; -import com.yanzhenjie.andserver.util.Assert; -import com.yanzhenjie.andserver.util.LinkedMultiValueMap; -import com.yanzhenjie.andserver.util.MediaType; -import com.yanzhenjie.andserver.util.MultiValueMap; -import ohos.hiviewdfx.HiLog; -import ohos.hiviewdfx.HiLogLabel; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileUpload; -import org.apache.commons.fileupload.FileUploadBase; -import org.apache.commons.fileupload.FileUploadException; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.io.Charsets; - -import java.io.File; -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/8/9. - */ -public class StandardMultipartResolver implements MultipartResolver { - - private DiskFileItemFactory mFileItemFactory; - private FileUpload mFileUpload; - - public StandardMultipartResolver() { - this.mFileItemFactory = new DiskFileItemFactory(); - this.mFileUpload = new FileUpload(mFileItemFactory); - } - - @Override - public void setAllFileMaxSize(long allFileMaxSize) { - this.mFileUpload.setSizeMax(allFileMaxSize); - } - - @Override - public void setFileMaxSize(long fileMaxSize) { - this.mFileUpload.setFileSizeMax(fileMaxSize); - } - - @Override - public void setMaxInMemorySize(int maxInMemorySize) { - this.mFileItemFactory.setSizeThreshold(maxInMemorySize); - } - - @Override - public void setUploadTempDir(File uploadTempDir) { - if (!uploadTempDir.exists() && !uploadTempDir.mkdirs()) { - String message = "Given uploadTempDir [" + uploadTempDir + "] could not be created."; - throw new IllegalArgumentException(message); - } - this.mFileItemFactory.setRepository(uploadTempDir); - } - - @Override - public boolean isMultipart(HttpRequest request) { - if (!request.getMethod().allowBody()) { - return false; - } - - RequestBody body = request.getBody(); - return body != null && FileUploadBase.isMultipartContent(new BodyContext(body)); - } - - @Override - public MultipartRequest resolveMultipart(HttpRequest request) throws MultipartException { - if (request instanceof MultipartRequest) { - return (MultipartRequest) request; - } - - MultipartParsingResult result = parseRequest(request); - return new StandardMultipartRequest(request, result.getMultipartFiles(), result.getMultipartParameters(), - result.getMultipartContentTypes()); - } - - @Override - public void cleanupMultipart(MultipartRequest request) { - if (request != null) { - try { - MultiValueMap multipartFiles = request.getMultiFileMap(); - for (List files: multipartFiles.values()) { - for (MultipartFile file: files) { - if (file instanceof StandardMultipartFile) { - StandardMultipartFile cmf = (StandardMultipartFile) file; - cmf.getFileItem().delete(); - } - } - } - } catch (Throwable ex) { - HiLog.warn(new HiLogLabel(0,1, AndServer.TAG),"Failed to perform multipart cleanup for servlet request."); - } - } - } - - /** - * Parse the given request, resolving its multipart elements. - * - * @param request the request to parse. - * - * @return the parsing result. - * - * @throws MultipartException if multipart resolution failed. - */ - private MultipartParsingResult parseRequest(HttpRequest request) throws MultipartException { - String encoding = determineEncoding(request); - FileUpload fileUpload = prepareFileUpload(encoding); - try { - RequestBody body = request.getBody(); - Assert.notNull(body, "The body cannot be null."); - List fileItems = fileUpload.parseRequest(new BodyContext(body)); - return parseFileItems(fileItems, encoding); - } catch (FileUploadBase.SizeLimitExceededException ex) { - throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex); - } catch (FileUploadBase.FileSizeLimitExceededException ex) { - throw new MaxUploadSizeExceededException(fileUpload.getFileSizeMax(), ex); - } catch (FileUploadException ex) { - throw new MultipartException("Failed to parse multipart servlet request.", ex); - } - } - - /** - * Determine the encoding for the given request. - * - *

The default implementation checks the request encoding, falling back to the default encoding specified for - * this resolver. - * - * @param request current request - * - * @return the encoding for the request . - */ - - private String determineEncoding(HttpRequest request) { - MediaType mimeType = request.getContentType(); - if (mimeType == null) { - return StandardCharsets.UTF_8.name(); - } - Charset charset = mimeType.getCharset(); - return charset == null ? StandardCharsets.UTF_8.name() : charset.name(); - } - - /** - * Determine an appropriate FileUpload instance for the given encoding. - * - *

Default implementation returns the shared FileUpload instance if the encoding matches, else creates a new - * FileUpload instance with the same configuration other than the desired encoding. - * - * @param encoding the character encoding to use. - * - * @return an appropriate FileUpload instance. - */ - private FileUpload prepareFileUpload( String encoding) { - FileUpload actualFileUpload = mFileUpload; - if (!encoding.equalsIgnoreCase(mFileUpload.getHeaderEncoding())) { - actualFileUpload = new FileUpload(mFileItemFactory); - actualFileUpload.setSizeMax(mFileUpload.getSizeMax()); - actualFileUpload.setFileSizeMax(mFileUpload.getFileSizeMax()); - actualFileUpload.setHeaderEncoding(encoding); - } - return actualFileUpload; - } - - /** - * Parse the given List of Commons FileItems into a MultipartParsingResult, containing MultipartFile instances and a - * Map of multipart parameter. - * - * @param fileItems the Commons FileItems to parse. - * @param encoding the encoding to use for form fields. - * - * @return the MultipartParsingResult. - * - * @see StandardMultipartFile#StandardMultipartFile(FileItem) - */ - protected MultipartParsingResult parseFileItems(List fileItems, String encoding) { - MultiValueMap multipartFiles = new LinkedMultiValueMap<>(); - MultiValueMap multipartParameters = new LinkedMultiValueMap<>(); - Map multipartContentTypes = new HashMap<>(); - - // Extract multipart files and multipart parameters. - for (FileItem fileItem: fileItems) { - if (fileItem.isFormField()) { - String value; - String partEncoding = determineEncoding(fileItem.getContentType(), encoding); - if (partEncoding != null) { - try { - value = fileItem.getString(partEncoding); - } catch (UnsupportedEncodingException ex) { - value = fileItem.getString(); - } - } else { - value = fileItem.getString(); - } - List curParam = multipartParameters.get(fileItem.getFieldName()); - if (curParam == null) { - // Simple form field. - curParam = new LinkedList<>(); - curParam.add(value); - multipartParameters.put(fileItem.getFieldName(), curParam); - } else { - // Array of simple form fields. - curParam.add(value); - } - multipartContentTypes.put(fileItem.getFieldName(), fileItem.getContentType()); - } else { - StandardMultipartFile file = createMultipartFile(fileItem); - multipartFiles.add(file.getName(), file); - } - } - return new MultipartParsingResult(multipartFiles, multipartParameters, multipartContentTypes); - } - - /** - * Create a {@link StandardMultipartFile} wrapper for the given Commons {@link FileItem}. - * - * @param fileItem the Commons FileItem to wrap. - * - * @return the corresponding StandardMultipartFile (potentially a custom subclass). - */ - protected StandardMultipartFile createMultipartFile(FileItem fileItem) { - return new StandardMultipartFile(fileItem); - } - - private String determineEncoding(String contentTypeHeader, String defaultEncoding) { - if (contentTypeHeader.isEmpty()) { - return defaultEncoding; - } - MediaType contentType = MediaType.parseMediaType(contentTypeHeader); - Charset charset = contentType.getCharset(); - return charset != null ? charset.name() : defaultEncoding; - } - - /** - * Holder for a Map of MultipartFiles and a Map of multipart parameters. - */ - protected static class MultipartParsingResult { - - private final MultiValueMap multipartFiles; - private final MultiValueMap multipartParameters; - private final Map multipartContentTypes; - - public MultipartParsingResult(MultiValueMap mpFiles, - MultiValueMap mpParams, - Map mpParamContentTypes) { - this.multipartFiles = mpFiles; - this.multipartParameters = mpParams; - this.multipartContentTypes = mpParamContentTypes; - } - - public MultiValueMap getMultipartFiles() { - return this.multipartFiles; - } - - public MultiValueMap getMultipartParameters() { - return this.multipartParameters; - } - - public Map getMultipartContentTypes() { - return this.multipartContentTypes; - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/IdGenerator.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/IdGenerator.java deleted file mode 100644 index 7430e082d9f5550dd2fdd868e3c39ec96db78ab9..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/IdGenerator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public interface IdGenerator { - - /** - * Generate and return a new identifier. - * - * @return the newly generated id. - */ - - String generateId(); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/Session.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/Session.java deleted file mode 100644 index 254dcc6590fefede0320fe0e367618e5e08f50f4..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/Session.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - - - -import java.util.Enumeration; - -/** - * Created by Zhenjie Yan on 2018/7/13. - */ -public interface Session { - - /** - * Returns a string containing the unique identifier assigned to this session. - */ - - String getId(); - - /** - * Returns the time when this session was created, measured in milliseconds since midnight January 1, 1970 GMT. - */ - long getCreatedTime(); - - /** - * Returns the last time the client sent a request associated with this session, as the number of milliseconds since - * midnight January 1, 1970 GMT, and marked by the time the container received the request. - * - *

Actions that your application takes, such as getting or setting a value associated with the session, do not - * affect the access time. - */ - long getLastAccessedTime(); - - /** - * Specifies the time, in seconds, between client requests before the server will invalidate this session. - * - *

An interval value of zero or less indicates that the session should never timeout. - * - * @param interval an integer specifying the number of seconds. - */ - void setMaxInactiveInterval(int interval); - - /** - * Returns the maximum time interval, in seconds, that the server will keep this session open between client - * accesses. After this interval, the server will invalidate the session. The maximum time interval can be set with - * the {@link #setMaxInactiveInterval(int)} method. - * - *

A return value of zero or less indicates that the session will never timeout. - */ - int getMaxInactiveInterval(); - - /** - * Returns the object bound with the specified name in this session, or {@code null} if no object is bound under the - * name. - * - * @param name a string specifying the name of the object. - */ - - Object getAttribute(String name); - - /** - * Returns an {@code Enumeration} of {@code String} objects containing the names of all the objects bound to this - * session. - */ - - Enumeration getAttributeNames(); - - /** - * Binds an object to this session, using the name specified. If an object of the same name is already bound to the - * session, the object is replaced. - * - *

If the value passed in is null, this has the same effect as calling {@link #removeAttribute(String)}. - * - * @param name the name to which the object is bound, cannot be null. - * @param value the object to be bound. - */ - void setAttribute(String name, Object value); - - /** - * Removes the object bound with the specified name from this session. If the session does not have an object bound - * with the specified name, this method does nothing. - * - * @param name the name of the object to remove from this session. - */ - void removeAttribute(String name); - - /** - * Invalidates this session then unbinds any objects bound to it. - */ - void invalidate(); - - /** - * Returns {@code true} if the client does not yet know about the session or if the client chooses not to join the - * session. E.g. if the server used only cookie-based sessions, and the client had disabled the use of cookies, then - * a session would be new on each request. - * - * @return {@code true} if the server has created a session, but the client has not yet joined. - */ - boolean isNew(); - - /** - * @return returns {@code true} is the session is valid, or false if the session is invalid. - */ - boolean isValid(); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/SessionManager.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/SessionManager.java deleted file mode 100644 index 5f58255f9cb74903ef9ff9ad2b9f44c1dadd1e48..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/SessionManager.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - - - -import java.io.IOException; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public interface SessionManager { - - /** - * Add this session to the set of active sessions for this {@code SessionManager}. - * - * @param session session to be added. - * - * @throws IOException if an output error occurs while processing this request. - */ - void add(Session session) throws IOException; - - /** - * Change the session ID of the current session to a new randomly generated session ID. - * - * @param session the session to change the session ID for. - */ - void changeSessionId(Session session); - - /** - * Create a new session object. - * - * @return an empty session object. - */ - - Session createSession(); - - /** - * Return the active session, with the specified session id (if any); otherwise return {@code null}. - * - * @param id the session id for the session to be returned. - * - * @return the request session or {@code null}. - * - * @throws IllegalStateException if a new session cannot be instantiated for any reason. - * @throws IOException if an output error occurs while processing this request. - */ - - Session findSession(String id) throws IOException, ClassNotFoundException; - - /** - * Remove this session from the active sessions for this {@code SessionManager}. - * - * @param session session to be removed. - */ - void remove(Session session); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardIdGenerator.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardIdGenerator.java deleted file mode 100644 index 87c9d30fd041df6629ab10df98725a368f159935..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardIdGenerator.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.http.session; - - - -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -public class StandardIdGenerator implements IdGenerator { - - private static final int ID_LENGTH = 30; - - private SecureRandom mRandom; - - public StandardIdGenerator() { - this.mRandom = createSecureRandom(); - } - - - @Override - public String generateId() { - byte random[] = new byte[16]; - - // Render the result as a String of hexadecimal digits. - // Start with enough space for sessionIdLength and medium route size. - StringBuilder buffer = new StringBuilder(2 * ID_LENGTH + 20); - - int resultLenBytes = 0; - - while (resultLenBytes < ID_LENGTH) { - mRandom.nextBytes(random); - for (int j = 0; j < random.length && resultLenBytes < ID_LENGTH; j++) { - byte b1 = (byte) ((random[j] & 0xf0) >> 4); - byte b2 = (byte) (random[j] & 0x0f); - if (b1 < 10) { - buffer.append((char) ('0' + b1)); - } else { - buffer.append((char) ('A' + (b1 - 10))); - } - if (b2 < 10) { - buffer.append((char) ('0' + b2)); - } else { - buffer.append((char) ('A' + (b2 - 10))); - } - resultLenBytes++; - } - } - return buffer.toString(); - } - - /** - * Create a new random number generator instance we should use for generating session identifiers. - */ - private SecureRandom createSecureRandom() { - SecureRandom result; - try { - result = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - result = new SecureRandom(); - } - - // Force seeding to take place. - result.nextInt(); - return result; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSession.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSession.java deleted file mode 100644 index f3507e22941a4a67e8c836330d2d4d71bd2559e4..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSession.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - -import com.yanzhenjie.andserver.util.Assert; -import com.yanzhenjie.andserver.util.StringUtils; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public class StandardSession implements Session { - - private static final String EMPTY_ARRAY[] = new String[0]; - private String id; - private long createdTime; - private long lastAccessedTime; - private int maxInactiveInterval = -1; - private Map mAttributes = new ConcurrentHashMap<>(); - private boolean isNew; - private boolean isValid; - - public StandardSession() { - } - - public void setId( String id) { - if (StringUtils.isEmpty(id)) { - throw new IllegalArgumentException("The id can not be empty or null."); - } - this.id = id; - } - - - @Override - public String getId() { - return id; - } - - public void setCreatedTime(long createdTime) { - this.createdTime = createdTime; - } - - @Override - public long getCreatedTime() { - return createdTime; - } - - public void setLastAccessedTime(long lastAccessedTime) { - this.lastAccessedTime = lastAccessedTime; - } - - @Override - public long getLastAccessedTime() { - validate(); - - return lastAccessedTime; - } - - @Override - public void setMaxInactiveInterval(int interval) { - this.maxInactiveInterval = interval; - } - - @Override - public int getMaxInactiveInterval() { - return maxInactiveInterval; - } - - @Override - public Object getAttribute(String name) { - validate(); - - if (name == null) { - return null; - } - return mAttributes.get(name); - } - - - @Override - public Enumeration getAttributeNames() { - validate(); - - return Collections.enumeration(new HashSet<>(mAttributes.keySet())); - } - - @Override - public void setAttribute( String name, Object value) { - validate(); - - Assert.notNull(name, "The name cannot be null."); - - if (value == null) { - return; - } - mAttributes.put(name, value); - } - - @Override - public void removeAttribute(String name) { - validate(); - - if (name == null) { - return; - } - mAttributes.remove(name); - } - - @Override - public void invalidate() { - validate(); - - this.isValid = false; - } - - public void setNew(boolean aNew) { - this.isNew = aNew; - } - - @Override - public boolean isNew() { - validate(); - - return isNew; - } - - private void validate() { - if (!isValid()) { - throw new IllegalStateException("This session is invalid."); - } - } - - public void setValid(boolean valid) { - this.isValid = valid; - } - - @Override - public boolean isValid() { - if (!isValid) { - return false; - } - - if (maxInactiveInterval > 0) { - long inactiveInterval = System.currentTimeMillis() - lastAccessedTime; - int timeIdle = (int) (inactiveInterval / 1000L); - if (timeIdle >= maxInactiveInterval) { - isValid = false; - } - } else { - isValid = true; - } - - return isValid; - } - - /** - * Write attribute values to the stream. - * - * @param stream stream. - * - * @throws IOException if the output error occurs while processing this request. - */ - public void writeObject( ObjectOutputStream stream) throws IOException { - stream.writeObject(id); - stream.writeLong(createdTime); - stream.writeLong(lastAccessedTime); - stream.writeInt(maxInactiveInterval); - stream.writeBoolean(isNew); - stream.writeBoolean(isValid); - stream.writeInt(mAttributes.size()); - String keys[] = mAttributes.keySet().toArray(EMPTY_ARRAY); - for (String key: keys) { - Object value = mAttributes.get(key); - if (value != null && value instanceof Serializable) { - stream.writeObject(key); - stream.writeObject(value); - } - } - } - - /** - * Read attribute values from the stream. - * - * @param stream stream. - * - * @throws IllegalStateException if a new session cannot be instantiated for any reason. - * @throws IOException if the input error occurs while processing this request. - */ - public final void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { - id = (String) stream.readObject(); - createdTime = stream.readLong(); - lastAccessedTime = stream.readLong(); - maxInactiveInterval = stream.readInt(); - isNew = stream.readBoolean(); - isValid = stream.readBoolean(); - - // Deserialize the attribute count and attribute values - int size = stream.readInt(); - for (int i = 0; i < size; i++) { - String name = (String) stream.readObject(); - Object value = stream.readObject(); - mAttributes.put(name, value); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSessionManager.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSessionManager.java deleted file mode 100644 index 83cb53d319386ff2df20fdadaa53a18754086452..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardSessionManager.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - -import ohos.app.Context; - -import java.io.File; -import java.io.IOException; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public class StandardSessionManager implements SessionManager { - - private IdGenerator mIdGenerator; - private Store mStore; - - public StandardSessionManager(Context context) { - this.mIdGenerator = new StandardIdGenerator(); - - File sessionDir = new File(context.getCacheDir(), "_andserver_session_"); - this.mStore = new StandardStore(sessionDir); - } - - @Override - public void add( Session session) throws IOException { - if (session instanceof StandardSession && session.isNew()) { - StandardSession standardSession = (StandardSession) session; - standardSession.setNew(false); - mStore.replace(standardSession); - } - } - - @Override - public void changeSessionId( Session session) { - if (session instanceof StandardSession) { - StandardSession standardSession = (StandardSession) session; - standardSession.setId(mIdGenerator.generateId()); - } - } - - - @Override - public Session createSession() { - StandardSession session = newSession(); - session.setId(mIdGenerator.generateId()); - return session; - } - - - @Override - public Session findSession( String id) throws IOException, ClassNotFoundException { - StandardSession session = mStore.getSession(id); - if (session != null) { - session.setLastAccessedTime(System.currentTimeMillis()); - } - return session; - } - - @Override - public void remove( Session session) { - if (session instanceof StandardSession) { - mStore.remove((StandardSession) session); - } - } - - private StandardSession newSession() { - StandardSession session = new StandardSession(); - long currentTime = System.currentTimeMillis(); - session.setCreatedTime(currentTime); - session.setLastAccessedTime(currentTime); - session.setNew(true); - session.setValid(true); - return session; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardStore.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardStore.java deleted file mode 100644 index 6adad190f099ab560fd9d9fd58f30eaf30222370..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/StandardStore.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - -import com.yanzhenjie.andserver.util.Assert; -import com.yanzhenjie.andserver.util.IOUtils; -import com.yanzhenjie.andserver.util.StringUtils; - -import java.io.*; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -public class StandardStore implements Store { - - private File mDirectory; - - public StandardStore(File directory) { - this.mDirectory = directory; - } - - @Override - public boolean replace( StandardSession session) throws IOException { - Assert.notNull(session, "The session can not be null."); - - String id = session.getId(); - if (StringUtils.isEmpty(id)) { - throw new IllegalStateException("The session id can not be empty or null."); - } - - ObjectOutputStream writer = null; - try { - if (!IOUtils.createFolder(mDirectory)) { - return false; - } - - File file = new File(mDirectory, id); - if (!IOUtils.createNewFile(file)) { - return false; - } - - writer = new ObjectOutputStream(new FileOutputStream(file)); - session.writeObject(writer); - return true; - } catch (IOException e) { - IOUtils.delFileOrFolder(new File(mDirectory, id)); - throw e; - } finally { - IOUtils.closeQuietly(writer); - } - } - - - @Override - public StandardSession getSession( String id) throws IOException, ClassNotFoundException { - if (id.isEmpty()) { - throw new IllegalArgumentException("The id can not be empty or null."); - } - - ObjectInputStream reader = null; - try { - File file = new File(mDirectory, id); - if (!file.exists() || file.isDirectory()) { - return null; - } - - reader = new ObjectInputStream(new FileInputStream(file)); - StandardSession session = new StandardSession(); - session.readObject(reader); - return session; - } catch (IOException e) { - IOUtils.delFileOrFolder(new File(mDirectory, id)); - throw e; - } finally { - IOUtils.closeQuietly(reader); - } - } - - @Override - public boolean remove( StandardSession session) { - String id = session.getId(); - if (id.isEmpty()) { - throw new IllegalStateException("The session id can not be empty or null."); - } - return IOUtils.delFileOrFolder(new File(mDirectory, session.getId())); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/http/session/Store.java b/api/src/main/java/com/yanzhenjie/andserver/http/session/Store.java deleted file mode 100644 index 53d90cbd1c6b7ad3956da8e22cbe7430ffbe5eaf..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/http/session/Store.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.http.session; - - - - -import java.io.IOException; - -/** - * Created by Zhenjie Yan on 2018/7/26. - */ -interface Store { - - /** - * Increase the session to the persistent store. - * - * @param session the session. - * - * @return true if it is successfully added or replaced, otherwise is false. - * - * @throws IOException if an output error occurs while processing this request. - */ - boolean replace(StandardSession session) throws IOException; - - /** - * Get the session from the persistent store. - * - * @param id the session ID. - * - * @return a session object. - * - * @throws IOException if the input error occurs while processing this request. - */ - - StandardSession getSession(String id) throws IOException, ClassNotFoundException; - - /** - * Remove the session from the persistent store. - * - * @param session the session. - * - * @return true if successful removal, otherwise is false. - */ - boolean remove(StandardSession session); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/register/OnRegister.java b/api/src/main/java/com/yanzhenjie/andserver/register/OnRegister.java deleted file mode 100644 index 2a93909a4ef8b5c1d0eb699f7bf5c16ce83d9554..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/register/OnRegister.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.register; - -import ohos.app.Context; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public interface OnRegister { - - /** - * Register the component. - * - * @param context context. - * @param group group name. - * @param register onRegister. - */ - void onRegister(Context context, String group, Register register); - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/register/Register.java b/api/src/main/java/com/yanzhenjie/andserver/register/Register.java deleted file mode 100644 index e1e0444789cd3fdbf5a4842011dbc4addc00fa93..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/register/Register.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.register; - - -import com.yanzhenjie.andserver.framework.ExceptionResolver; -import com.yanzhenjie.andserver.framework.HandlerInterceptor; -import com.yanzhenjie.andserver.framework.MessageConverter; -import com.yanzhenjie.andserver.framework.config.Multipart; -import com.yanzhenjie.andserver.framework.handler.HandlerAdapter; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public interface Register { - - /** - * Increase the handler adapter. - * - * @param adapter {@link HandlerAdapter}. - */ - void addAdapter(HandlerAdapter adapter); - - /** - * Increase handler interceptor. - * - * @param interceptor {@link HandlerInterceptor}. - */ - void addInterceptor(HandlerInterceptor interceptor); - - /** - * Set up a message converter to convert messages that are not recognized by AndServer. - * - * @param converter {@link MessageConverter}. - */ - void setConverter(MessageConverter converter); - - /** - * Set the exception handler. If you don't want you to let AndServer output the default error message, set it to - * take over the exception. - * - * @param resolver {@link ExceptionResolver}. - */ - void setResolver(ExceptionResolver resolver); - - /** - * Set the parameters used to resolve the multipart request. - * - * @param multipart {@link Multipart}. - */ - void setMultipart(Multipart multipart); -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/server/BasicServer.java b/api/src/main/java/com/yanzhenjie/andserver/server/BasicServer.java deleted file mode 100644 index 0e7e51bfbccc620730117e03a47785db53a5f974..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/server/BasicServer.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.server; - -import com.yanzhenjie.andserver.AndServer; -import com.yanzhenjie.andserver.SSLSocketInitializer; -import com.yanzhenjie.andserver.Server; -import com.yanzhenjie.andserver.util.Executors; -import org.apache.httpcore.ExceptionLogger; -import org.apache.httpcore.config.SocketConfig; -import org.apache.httpcore.impl.bootstrap.HttpServer; -import org.apache.httpcore.impl.bootstrap.SSLServerSetupHandler; -import org.apache.httpcore.impl.bootstrap.ServerBootstrap; -import org.apache.httpcore.protocol.HttpRequestHandler; - -import javax.net.ServerSocketFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLServerSocket; -import java.net.InetAddress; -import java.util.concurrent.TimeUnit; - -/** - * Created by Zhenjie Yan on 3/7/20. - */ -public abstract class BasicServer implements Server { - - static final int BUFFER = 8 * 1024; - - protected final InetAddress mInetAddress; - protected final int mPort; - protected final int mTimeout; - protected final ServerSocketFactory mSocketFactory; - protected final SSLContext mSSLContext; - protected final SSLSocketInitializer mSSLSocketInitializer; - protected final Server.ServerListener mListener; - - private HttpServer mHttpServer; - protected boolean isRunning; - - BasicServer(T builder) { - this.mInetAddress = builder.inetAddress; - this.mPort = builder.port; - this.mTimeout = builder.timeout; - this.mSocketFactory = builder.mSocketFactory; - this.mSSLContext = builder.sslContext; - this.mSSLSocketInitializer = builder.mSSLSocketInitializer; - this.mListener = builder.listener; - } - - @Override - public boolean isRunning() { - return isRunning; - } - - @Override - public void startup() { - if (isRunning) { - return; - } - - Executors.getInstance().execute(new Runnable() { - @Override - public void run() { - try { - mHttpServer = ServerBootstrap.bootstrap() - .setServerSocketFactory(mSocketFactory) - .setSocketConfig( - SocketConfig.custom() - .setSoKeepAlive(true) - .setSoReuseAddress(true) - .setTcpNoDelay(true) - .setSoTimeout(mTimeout) - .setBacklogSize(BUFFER) - .setRcvBufSize(BUFFER) - .setSndBufSize(BUFFER) - .setSoLinger(0) - .build() - ) - .setLocalAddress(mInetAddress) - .setListenerPort(mPort) - .setSslContext(mSSLContext) - .setSslSetupHandler(new SSLSetup(mSSLSocketInitializer)) - .setServerInfo(AndServer.INFO) - .registerHandler("*", requestHandler()) - .setExceptionLogger(ExceptionLogger.NO_OP) - .create(); - - mHttpServer.start(); - isRunning = true; - - 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.onException(e); - } - } - }); - } - } - }); - } - - /** - * Assigns {@link HttpRequestHandler} instance. - */ - protected abstract HttpRequestHandler requestHandler(); - - /** - * Quit the server. - */ - @Override - public void shutdown() { - if (!isRunning) { - return; - } - - Executors.getInstance().execute(new Runnable() { - @Override - public void run() { - if (mHttpServer != null) { - mHttpServer.shutdown(3, TimeUnit.SECONDS); - isRunning = false; - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) { - mListener.onStopped(); - } - } - }); - } - } - }); - } - - private static final class SSLSetup implements SSLServerSetupHandler { - - private final SSLSocketInitializer mInitializer; - - public SSLSetup( SSLSocketInitializer initializer) { - this.mInitializer = initializer; - } - - @Override - public void initialize(SSLServerSocket socket) throws SSLException { - mInitializer.onCreated(socket); - } - } - - @Override - public InetAddress getInetAddress() { - if (isRunning) { - return mHttpServer.getInetAddress(); - } - throw new IllegalStateException("The server has not been started yet."); - } - - @Override - public int getPort() { - if (isRunning) { - return mHttpServer.getLocalPort(); - } - throw new IllegalStateException("The server has not been started yet."); - } - - protected abstract static class Builder { - - InetAddress inetAddress; - int port; - int timeout; - ServerSocketFactory mSocketFactory; - SSLContext sslContext; - SSLSocketInitializer mSSLSocketInitializer; - Server.ServerListener listener; - - Builder() { - } - @SuppressWarnings("unchecked") - public T inetAddress(InetAddress inetAddress) { - this.inetAddress = inetAddress; - return (T) this; - } - @SuppressWarnings("unchecked") - public T port(int port) { - this.port = port; - return (T) this; - } - @SuppressWarnings("unchecked") - public T timeout(int timeout, TimeUnit timeUnit) { - long timeoutMs = timeUnit.toMillis(timeout); - this.timeout = (int) Math.min(timeoutMs, Integer.MAX_VALUE); - return (T) this; - } - @SuppressWarnings("unchecked") - public T serverSocketFactory(ServerSocketFactory factory) { - this.mSocketFactory = factory; - return (T) this; - } - @SuppressWarnings("unchecked") - public T sslContext(SSLContext sslContext) { - this.sslContext = sslContext; - return (T) this; - } - @SuppressWarnings("unchecked") - public T sslSocketInitializer(SSLSocketInitializer initializer) { - this.mSSLSocketInitializer = initializer; - return (T) this; - } - @SuppressWarnings("unchecked") - public T listener(Server.ServerListener listener) { - this.listener = listener; - return (T) this; - } - - public abstract S build(); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/server/ProxyServer.java b/api/src/main/java/com/yanzhenjie/andserver/server/ProxyServer.java deleted file mode 100644 index 6bbaee6ef8d4db3d2adc2c5c79a70bfab80322ba..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/server/ProxyServer.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.server; - - -import com.yanzhenjie.andserver.AndServer; -import com.yanzhenjie.andserver.ProxyHandler; -import com.yanzhenjie.andserver.SSLSocketInitializer; -import com.yanzhenjie.andserver.Server; -import com.yanzhenjie.andserver.util.Executors; -import org.apache.httpcore.ConnectionClosedException; -import org.apache.httpcore.HttpException; -import org.apache.httpcore.HttpHost; -import org.apache.httpcore.HttpServerConnection; -import org.apache.httpcore.impl.DefaultBHttpClientConnection; -import org.apache.httpcore.impl.DefaultBHttpServerConnection; -import org.apache.httpcore.protocol.*; - -import javax.net.ServerSocketFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLServerSocket; -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Created by Zhenjie Yan on 3/7/20. - */ -public class ProxyServer extends BasicServer { - - public static final String PROXY_CONN_CLIENT = "http.proxy.conn.client"; - public static final String PROXY_CONN_ALIVE = "http.proxy.conn.alive"; - - public static Builder newBuilder() { - return new Builder(); - } - - private final InetAddress mInetAddress; - private final int mPort; - private final int mTimeout; - private final ServerSocketFactory mSocketFactory; - private final SSLContext mSSLContext; - private final SSLSocketInitializer mSSLSocketInitializer; - private final Server.ServerListener mListener; - - private Map mHostList; - - private HttpServer mHttpServer; - private boolean isRunning; - - private ProxyServer(Builder builder) { - super(builder); - this.mInetAddress = builder.inetAddress; - this.mPort = builder.port; - this.mTimeout = builder.timeout; - this.mSocketFactory = builder.mSocketFactory; - this.mSSLContext = builder.sslContext; - this.mSSLSocketInitializer = builder.mSSLSocketInitializer; - this.mListener = builder.listener; - - this.mHostList = builder.mHostList; - } - - @Override - protected HttpRequestHandler requestHandler() { - return new ProxyHandler(mHostList); - } - - @Override - public void startup() { - if (isRunning) { - return; - } - - Executors.getInstance().execute(new Runnable() { - @Override - public void run() { - ServerSocketFactory socketFactory = mSocketFactory; - if (socketFactory == null) { - if (mSSLContext != null) { - socketFactory = mSSLContext.getServerSocketFactory(); - } else { - socketFactory = ServerSocketFactory.getDefault(); - } - } - - mHttpServer = new HttpServer(mInetAddress, - mPort, - mTimeout, - socketFactory, - mSSLSocketInitializer, - requestHandler()); - try { - mHttpServer.startServer(); - isRunning = true; - - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) { - mListener.onStarted(); - } - } - }); - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - mHttpServer.stopServer(); - } - }); - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - - @Override - public void shutdown() { - if (!isRunning) { - return; - } - - Executors.getInstance().execute(new Runnable() { - @Override - public void run() { - if (mHttpServer != null) { - mHttpServer.stopServer(); - isRunning = false; - Executors.getInstance().post(new Runnable() { - @Override - public void run() { - if (mListener != null) { - mListener.onStopped(); - } - } - }); - } - } - }); - } - - public static class Builder extends BasicServer.Builder - implements Server.ProxyBuilder { - - private Map mHostList = new HashMap<>(); - - public Builder() { - } - - @Override - public Builder addProxy(String hostName, String proxyHost) { - mHostList.put(hostName.toLowerCase(Locale.ROOT), HttpHost.create(proxyHost)); - return this; - } - - @Override - public ProxyServer build() { - return new ProxyServer(this); - } - } - - private static class HttpServer implements Runnable { - - private final InetAddress mInetAddress; - private final int mPort; - private final int mTimeout; - private final ServerSocketFactory mSocketFactory; - private final SSLSocketInitializer mSSLSocketInitializer; - private final HttpRequestHandler mHandler; - - private final ThreadPoolExecutor mServerExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, - new SynchronousQueue<>(), new ThreadFactoryImpl("HTTP-Server-")); - private final ThreadGroup mWorkerThreads = new ThreadGroup("HTTP-workers"); - private final ThreadPoolExecutor mWorkerExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 1L, - TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactoryImpl("HTTP-Handlers-", mWorkerThreads)) { - @Override - protected void beforeExecute(Thread t, Runnable r) { - if (r instanceof Worker) { - mWorkerSet.put((Worker) r, Boolean.TRUE); - } - } - - @Override - protected void afterExecute(Runnable r, Throwable t) { - if (r instanceof Worker) { - mWorkerSet.remove(r); - } - } - }; - private final Map mWorkerSet = new ConcurrentHashMap<>(); - - private HttpService mHttpService; - private ServerSocket mServerSocket; - - public HttpServer(InetAddress inetAddress, int port, int timeout, ServerSocketFactory socketFactory, - SSLSocketInitializer sslSocketInitializer, HttpRequestHandler handler) { - this.mInetAddress = inetAddress; - this.mPort = port; - this.mTimeout = timeout; - this.mSocketFactory = socketFactory; - this.mSSLSocketInitializer = sslSocketInitializer; - this.mHandler = handler; - - HttpProcessor inProcessor = new ImmutableHttpProcessor( - new ResponseDate(), - new ResponseServer(AndServer.INFO), - new ResponseContent(), - new ResponseConnControl()); - - UriHttpRequestHandlerMapper mapper = new UriHttpRequestHandlerMapper(); - mapper.register("*", mHandler); - - this.mHttpService = new HttpService(inProcessor, mapper); - } - - public void startServer() throws IOException { - mServerSocket = mSocketFactory.createServerSocket(); - mServerSocket.setReuseAddress(true); - mServerSocket.bind(new InetSocketAddress(mInetAddress, mPort), BUFFER); - mServerSocket.setReceiveBufferSize(BUFFER); - if (mSSLSocketInitializer != null && mServerSocket instanceof SSLServerSocket) { - mSSLSocketInitializer.onCreated((SSLServerSocket) mServerSocket); - } - - mServerExecutor.execute(this); - } - - public void stopServer() { - mServerExecutor.shutdown(); - mWorkerExecutor.shutdown(); - try { - mServerSocket.close(); - } catch (IOException ignored) { - } - mWorkerThreads.interrupt(); - - try { - mWorkerExecutor.awaitTermination(3, TimeUnit.SECONDS); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - - Set workers = mWorkerSet.keySet(); - for (Worker worker : workers) { - HttpServerConnection conn = worker.getServerConn(); - try { - conn.shutdown(); - } catch (IOException ignored) { - } - } - } - - @Override - public void run() { - try { - while (!Thread.interrupted()) { - Socket socket = mServerSocket.accept(); - socket.setSoTimeout(mTimeout); - socket.setKeepAlive(true); - socket.setTcpNoDelay(true); - socket.setReceiveBufferSize(BUFFER); - socket.setSendBufferSize(BUFFER); - socket.setSoLinger(true, 0); - - DefaultBHttpServerConnection serverConn = new DefaultBHttpServerConnection(BUFFER); - serverConn.bind(socket); - - DefaultBHttpClientConnection clientConn = new DefaultBHttpClientConnection(BUFFER); - Worker worker = new Worker(mHttpService, serverConn, clientConn); - - mWorkerExecutor.execute(worker); - } - } catch (Exception ignored) { - } - } - } - - private static class Worker implements Runnable { - - private final HttpService mHttpService; - private final DefaultBHttpServerConnection mServerConn; - private final DefaultBHttpClientConnection mClientConn; - - public Worker(HttpService httpservice, - DefaultBHttpServerConnection serverConn, DefaultBHttpClientConnection clientConn) { - this.mHttpService = httpservice; - this.mServerConn = serverConn; - this.mClientConn = clientConn; - } - - public DefaultBHttpServerConnection getServerConn() { - return mServerConn; - } - - @Override - public void run() { - BasicHttpContext localContext = new BasicHttpContext(); - HttpCoreContext context = HttpCoreContext.adapt(localContext); - context.setAttribute(PROXY_CONN_CLIENT, mClientConn); - - try { - while (!Thread.interrupted()) { - if (!mServerConn.isOpen()) { - mClientConn.close(); - break; - } - - mHttpService.handleRequest(mServerConn, context); - - Boolean keepAlive = (Boolean) context.getAttribute(PROXY_CONN_ALIVE); - if (!Boolean.TRUE.equals(keepAlive)) { - mClientConn.close(); - mServerConn.close(); - break; - } - } - } catch (ConnectionClosedException ex) { - System.err.println("Client closed connection."); - } catch (IOException ex) { - System.err.println("I/O error: " + ex.getMessage()); - } catch (HttpException ex) { - System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage()); - } finally { - try { - mServerConn.shutdown(); - } catch (IOException ignore) { - } - try { - mClientConn.shutdown(); - } catch (IOException ignore) { - } - } - } - } - - private static class ThreadFactoryImpl implements ThreadFactory { - private final String mPrefix; - private final ThreadGroup mGroup; - private final AtomicLong mCount; - - ThreadFactoryImpl(String prefix, ThreadGroup group) { - this.mPrefix = prefix; - this.mGroup = group; - this.mCount = new AtomicLong(); - } - - ThreadFactoryImpl(String mPrefix) { - this(mPrefix, null); - } - - @Override - public Thread newThread( Runnable target) { - return new Thread(mGroup, target, mPrefix + "-" + mCount.incrementAndGet()); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/server/WebServer.java b/api/src/main/java/com/yanzhenjie/andserver/server/WebServer.java deleted file mode 100644 index cbd3a3e92f912037d52ea4a9fda1db527a296d2d..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/server/WebServer.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.server; - -import com.yanzhenjie.andserver.ComponentRegister; -import com.yanzhenjie.andserver.DispatcherHandler; -import com.yanzhenjie.andserver.Server; -import ohos.app.Context; -import org.apache.httpcore.protocol.HttpRequestHandler; - -/** - * Created by Zhenjie Yan on 3/7/20. - */ -public class WebServer extends BasicServer { - - public static Builder newBuilder(Context context, String group) { - return new Builder(context, group); - } - - private Context mContext; - private String mGroup; - - private WebServer(Builder builder) { - super(builder); - this.mContext = builder.context; - this.mGroup = builder.group; - } - - @Override - protected HttpRequestHandler requestHandler() { - DispatcherHandler handler = new DispatcherHandler(mContext); - ComponentRegister register = new ComponentRegister(mContext); - try { - register.register(handler, mGroup); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - return handler; - } - - public static class Builder extends BasicServer.Builder - implements Server.Builder { - - private Context context; - private String group; - - private Builder(Context context, String group) { - this.context = context; - this.group = group; - } - - @Override - public WebServer build() { - return new WebServer(this); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/AcceptLanguage.java b/api/src/main/java/com/yanzhenjie/andserver/util/AcceptLanguage.java deleted file mode 100644 index 8419bf515452d3366b981d056dd98efcac1a043e..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/AcceptLanguage.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.yanzhenjie.andserver.http.FAcceptLanguage; - -import java.util.Locale; - -/** - * Created by Zhenjie Yan on 2018/8/7. - * - * @deprecated use {@link FAcceptLanguage} instead. - */ -@Deprecated -public class AcceptLanguage extends FAcceptLanguage { - - protected AcceptLanguage(Locale locale, double quality) { - super(locale, quality); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/Assert.java b/api/src/main/java/com/yanzhenjie/andserver/util/Assert.java deleted file mode 100644 index 04173d6db82f52e36928c5384dfb7fb51f0245fe..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/Assert.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.util.Collection; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/7/5. - */ -public abstract class Assert { - - /** - * Assert a boolean expression, throwing an {@code IllegalStateException} if the expression evaluates to {@code - * false}. - * - *

Call {@link #isTrue} if you wish to throw an {@code IllegalArgumentException} on an assertion failure.

Assert.state(id == null, "The id property must not already be initialized");
- * - * @param expression a boolean expression. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalStateException if {@code expression} is {@code false} - */ - public static void state(boolean expression, String message) { - if (!expression) { - throw new IllegalStateException(message); - } - } - - /** - * Assert a boolean expression, throwing an {@code IllegalArgumentException} if the expression evaluates to {@code - * false}. - * - *
Assert.isTrue(i > 0, "The value must be greater than zero");
- * - * @param expression a boolean expression. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if {@code expression} is {@code false}. - */ - public static void isTrue(boolean expression, String message) { - if (!expression) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an object is {@code null}. - * - *
Assert.isNull(value, "The value must be null");
- * - * @param object the object to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the object is not {@code null}. - */ - public static void isNull(Object object, String message) { - if (object != null) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an object is not {@code null}. - * - *
Assert.notNull(clazz, "The class must not be null");
- * - * @param object the object to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the object is {@code null} - */ - public static void notNull(Object object, String message) { - if (object == null) { - throw new IllegalArgumentException(message); - } - } - - - /** - * Assert that the given String is not empty; that is, it must not be {@code null} and not the empty String. - * - *
Assert.hasLength(name, "Name must not be empty");
- * - * @param text the String to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the text is empty. - */ - public static void hasLength(String text, String message) { - if (text.isEmpty()) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given String contains valid text content; that is, it must not be {@code null} and must contain - * at least one non-whitespace character. - * - *
Assert.hasText(name, "'name' must not be empty");
- * - * @param text the String to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the text does not contain valid text content. - */ - public static void hasText(String text, String message) { - if (text.isEmpty()) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given text does not contain the given substring. - * - *
Assert .doesNotContain(name, "rod", "Name must not contain 'rod'");
- * - * @param textToSearch the text to search. - * @param substring the substring to find within the text. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the text contains the substring. - */ - public static void doesNotContain(String textToSearch, String substring, String message) { - if (!textToSearch.isEmpty() && !substring.isEmpty() && textToSearch.contains(substring)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an array contains elements; that is, it must not be {@code null} and must contain at least one - * element. - * - *
Assert.notEmpty(array, "The array must contain elements");
- * - * @param array the array to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the object array is {@code null} or contains no elements. - */ - public static void notEmpty(Object[] array, String message) { - if (array == null || array.length == 0) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an array contains no {@code null} elements.

Note: Does not complain if the array is empty! - * - *

Assert.noNullElements(array, "The array must contain non-null elements");
- * - * @param array the array to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the object array contains a {@code null} element. - */ - public static void noNullElements(Object[] array, String message) { - if (array != null) { - for (Object element: array) { - if (element == null) { - throw new IllegalArgumentException(message); - } - } - } - } - - /** - * Assert that a collection contains elements; that is, it must not be {@code null} and must contain at least one - * element. - * - *
Assert.notEmpty(collection, "Collection must contain elements");
- * - * @param collection the collection to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the collection is {@code null} or contains no elements. - */ - public static void notEmpty(Collection collection, String message) { - if (collection == null || collection.isEmpty()) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that a Map contains entries; that is, it must not be {@code null} and must contain at least one entry. - * - *
Assert.notEmpty(map, "Map must contain entries");
- * - * @param map the map to check. - * @param message the exception message to use if the assertion fails. - * - * @throws IllegalArgumentException if the map is {@code null} or contains no entries. - */ - public static void notEmpty(Map map, String message) { - if (map == null || map.isEmpty()) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the provided object is an instance of the provided class. - * - *
Assert.instanceOf(Foo.class, foo, "Foo expected");
- * - * @param type the type to check against. - * @param obj the object to check. - * @param message a message which will be prepended to provide further context. If it is empty or ends in ":" or - * ";" or "," or ".", a full exception message will be appended. If it ends in a space, the name of the - * offending object's type will be appended. In any other case, a ":" with a space and the name of the offending - * object's type will be appended. - * - * @throws IllegalArgumentException if the object is not an instance of type. - */ - public static void isInstanceOf(Class type, Object obj, String message) { - notNull(type, "Type to check against must not be null"); - - if (!type.isInstance(obj)) { - instanceCheckFailed(type, obj, message); - } - } - - /** - * Assert that the provided object is an instance of the provided class. - * - *
Assert.instanceOf(Foo.class, foo);
- * - * @param type the type to check against. - * @param obj the object to check. - * - * @throws IllegalArgumentException if the object is not an instance of type. - */ - public static void isInstanceOf(Class type, Object obj) { - isInstanceOf(type, obj, ""); - } - - /** - * Assert that {@code superType.isAssignableFrom(subType)} is {@code true}. - * - *
Assert.isAssignable(Number.class, myClass, "Number expected");
- * - * @param superType the super type to check against. - * @param subType the sub type to check. - * @param message a message which will be prepended to provide further context. If it is empty or ends in ":" or - * ";" or "," or ".", a full exception message will be appended. If it ends in a space, the name of the - * offending sub type will be appended. In any other case, a ":" with a space and the name of the offending sub - * type will be appended. - * - * @throws IllegalArgumentException if the classes are not assignable. - */ - public static void isAssignable(Class superType, Class subType, String message) { - notNull(superType, "Super type to check against must not be null"); - - if (subType == null || !superType.isAssignableFrom(subType)) { - assignableCheckFailed(superType, subType, message); - } - } - - /** - * Assert that {@code superType.isAssignableFrom(subType)} is {@code true}. - * - *
Assert.isAssignable(Number.class, myClass);
- * - * @param superType the super type to check. - * @param subType the sub type to check. - * - * @throws IllegalArgumentException if the classes are not assignable. - */ - public static void isAssignable(Class superType, Class subType) { - isAssignable(superType, subType, ""); - } - - private static void instanceCheckFailed(Class type, Object obj, String msg) { - String className = (obj != null ? obj.getClass().getName() : "null"); - String result = ""; - boolean defaultMessage = true; - if (!msg.isEmpty()) { - if (endsWithSeparator(msg)) { - result = msg + " "; - } else { - result = messageWithTypeName(msg, className); - defaultMessage = false; - } - } - if (defaultMessage) { - result = result + ("Object of class [" + className + "] must be an instance of " + type); - } - throw new IllegalArgumentException(result); - } - - private static void assignableCheckFailed(Class superType, Class subType, String msg) { - String result = ""; - boolean defaultMessage = true; - if (!msg.isEmpty()) { - if (endsWithSeparator(msg)) { - result = msg + " "; - } else { - result = messageWithTypeName(msg, subType); - defaultMessage = false; - } - } - if (defaultMessage) { - result = result + (subType + " is not assignable to " + superType); - } - throw new IllegalArgumentException(result); - } - - private static boolean endsWithSeparator(String msg) { - return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith(".")); - } - - private static String messageWithTypeName(String msg, Object typeName) { - return msg + (msg.endsWith(" ") ? "" : ": ") + typeName; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/CollectionUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/CollectionUtils.java deleted file mode 100644 index d80c7a3596c0496d52b3237b3355e012a1344018..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/CollectionUtils.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.Serializable; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/7/11. - * - * @deprecated use apache commons-collection instead. - */ -@Deprecated -public abstract class CollectionUtils { - - /** - * Return {@code true} if the supplied Collection is {@code null} or empty. Otherwise, return {@code false}. - * - * @param collection the Collection to check. - * - * @return whether the given Collection is empty. - */ - public static boolean isEmpty(Collection collection) { - return (collection == null || collection.isEmpty()); - } - - /** - * Return {@code true} if the supplied Map is {@code null} or empty. Otherwise, return {@code false}. - * - * @param map the Map to check. - * - * @return whether the given Map is empty. - */ - public static boolean isEmpty(Map map) { - return (map == null || map.isEmpty()); - } - - /** - * Convert the supplied array into a List. StandardCookieProcessor primitive array gets converted into a List of the - * appropriate wrapper type. - * - *

NOTE: Generally prefer the standard {@link Arrays#asList} method. This {@code arrayToList} method is - * just meant to deal with an incoming Object value that might be an {@code Object[]} or a primitive array at - * runtime. - * - *

StandardCookieProcessor {@code null} source value will be converted to an empty List. - * - * @param source the (potentially primitive) array. - * - * @return the converted List result. - */ - public static List arrayToList(Object source) { - return Arrays.asList(ObjectUtils.toObjectArray(source)); - } - - /** - * Merge the given array into the given Collection. - * - * @param array the array to merge (may be {@code null}). - * @param collection the target Collection to merge the array into. - */ - @SuppressWarnings("unchecked") - public static void mergeArrayIntoCollection(Object array, Collection collection) { - if (collection == null) { - throw new IllegalArgumentException("Collection must not be null"); - } - Object[] arr = ObjectUtils.toObjectArray(array); - for (Object elem: arr) { - collection.add((E) elem); - } - } - - /** - * Merge the given Properties instance into the given Map, copying all properties (key-value pairs) over.

Uses - * {@code Properties.propertyNames()} to even catch default properties linked into the original Properties - * instance. - * - * @param props the Properties instance to merge (may be {@code null}). - * @param map the target Map to merge the properties into. - */ - @SuppressWarnings("unchecked") - public static void mergePropertiesIntoMap(Properties props, Map map) { - if (map == null) { - throw new IllegalArgumentException("Map must not be null"); - } - if (props != null) { - for (Enumeration en = props.propertyNames(); en.hasMoreElements(); ) { - String key = (String) en.nextElement(); - Object value = props.get(key); - if (value == null) { - // Allow for defaults fallback or potentially overridden accessor... - value = props.getProperty(key); - } - map.put((K) key, (V) value); - } - } - } - - - /** - * Check whether the given Iterator contains the given element. - * - * @param iterator the Iterator to check. - * @param element the element to look for. - * - * @return {@code true} if found, {@code false} else. - */ - public static boolean contains(Iterator iterator, Object element) { - if (iterator != null) { - while (iterator.hasNext()) { - Object candidate = iterator.next(); - if (ObjectUtils.nullSafeEquals(candidate, element)) { - return true; - } - } - } - return false; - } - - /** - * Check whether the given Enumeration contains the given element. - * - * @param enumeration the Enumeration to check. - * @param element the element to look for. - * - * @return {@code true} if found, {@code false} else. - */ - public static boolean contains(Enumeration enumeration, Object element) { - if (enumeration != null) { - while (enumeration.hasMoreElements()) { - Object candidate = enumeration.nextElement(); - if (ObjectUtils.nullSafeEquals(candidate, element)) { - return true; - } - } - } - return false; - } - - /** - * Check whether the given Collection contains the given element instance.

Enforces the given instance to be - * present, rather than returning {@code true} for an equal element as well. - * - * @param collection the Collection to check. - * @param element the element to look for. - * - * @return {@code true} if found, {@code false} else. - */ - public static boolean containsInstance(Collection collection, Object element) { - if (collection != null) { - for (Object candidate: collection) { - if (candidate == element) { - return true; - } - } - } - return false; - } - - /** - * Return {@code true} if any element in '{@code candidates}' is contained in '{@code source}'; otherwise returns - * {@code false}. - * - * @param source the source Collection. - * @param candidates the candidates to search for. - * - * @return whether any of the candidates has been found. - */ - public static boolean containsAny(Collection source, Collection candidates) { - if (isEmpty(source) || isEmpty(candidates)) { - return false; - } - for (Object candidate: candidates) { - if (source.contains(candidate)) { - return true; - } - } - return false; - } - - /** - * Return the first element in '{@code candidates}' that is contained in '{@code source}'. If no element in '{@code - * candidates}' is present in '{@code source}' returns {@code null}. Iteration order is {@link Collection} - * implementation specific. - * - * @param source the source Collection. - * @param candidates the candidates to search for. - * - * @return the first present object, or {@code null} if not found. - */ - @SuppressWarnings("unchecked") - public static E findFirstMatch(Collection source, Collection candidates) { - if (isEmpty(source) || isEmpty(candidates)) { - return null; - } - for (Object candidate: candidates) { - if (source.contains(candidate)) { - return (E) candidate; - } - } - return null; - } - - /** - * Find a single value of the given type in the given Collection. - * - * @param collection the Collection to search. - * @param type the type to look for. - * - * @return a value of the given type found if there is a clear match, or {@code null} if none or more than one such - * value found. - */ - @SuppressWarnings("unchecked") - public static T findValueOfType(Collection collection, Class type) { - if (isEmpty(collection)) { - return null; - } - T value = null; - for (Object element: collection) { - if (type == null || type.isInstance(element)) { - if (value != null) { - // More than one value found... no clear single value. - return null; - } - value = (T) element; - } - } - return value; - } - - /** - * Find a single value of one of the given types in the given Collection: searching the Collection for a value of - * the first type, then searching for a value of the second type, etc. - * - * @param collection the collection to search. - * @param types the types to look for, in prioritized order. - * - * @return a value of one of the given types found if there is a clear match, or {@code null} if none or more than - * one such value found. - */ - public static Object findValueOfType(Collection collection, Class[] types) { - if (isEmpty(collection) || ObjectUtils.isEmpty(types)) { - return null; - } - for (Class type: types) { - Object value = findValueOfType(collection, type); - if (value != null) { - return value; - } - } - return null; - } - - /** - * Determine whether the given Collection only contains a single unique object. - * - * @param collection the Collection to check. - * - * @return {@code true} if the collection contains a single reference or multiple references to the same instance, - * {@code false} else. - */ - public static boolean hasUniqueObject(Collection collection) { - if (isEmpty(collection)) { - return false; - } - boolean hasCandidate = false; - Object candidate = null; - for (Object elem: collection) { - if (!hasCandidate) { - hasCandidate = true; - candidate = elem; - } else if (candidate != elem) { - return false; - } - } - return true; - } - - /** - * Find the common element type of the given Collection, if any. - * - * @param collection the Collection to check. - * - * @return the common element type, or {@code null} if no clear common type has been found (or the collection was - * empty). - */ - public static Class findCommonElementType(Collection collection) { - if (isEmpty(collection)) { - return null; - } - Class candidate = null; - for (Object val: collection) { - if (val != null) { - if (candidate == null) { - candidate = val.getClass(); - } else if (candidate != val.getClass()) { - return null; - } - } - } - return candidate; - } - - /** - * Marshal the elements from the given enumeration into an array of the given type. Enumeration elements must be - * assignable to the type of the given array. The array returned will be a different instance than the array given. - */ - public static A[] toArray(Enumeration enumeration, A[] array) { - ArrayList elements = new ArrayList<>(); - while (enumeration.hasMoreElements()) { - elements.add(enumeration.nextElement()); - } - return elements.toArray(array); - } - - /** - * Adapt an enumeration to an iterator. - * - * @param enumeration the enumeration. - * - * @return the iterator. - */ - public static Iterator toIterator(Enumeration enumeration) { - return new EnumerationIterator<>(enumeration); - } - - /** - * Adapt a {@code Map>} to an {@code MultiValueMap}. - * - * @param map the original map. - * - * @return the multi-value map. - */ - public static MultiValueMap toMultiValueMap(Map> map) { - return new MultiValueMapAdapter<>(map); - } - - /** - * Return an unmodifiable view of the specified multi-value map. - * - * @param map the map for which an unmodifiable view is to be returned. - * - * @return an unmodifiable view of the specified multi-value map. - */ - @SuppressWarnings("unchecked") - public static MultiValueMap unmodifiableMultiValueMap(MultiValueMap map) { - Assert.notNull(map, "'map' must not be null"); - Map> result = new LinkedHashMap<>(map.size()); - for (Map.Entry> entry: map.entrySet()) { - List values = Collections.unmodifiableList(entry.getValue()); - result.put(entry.getKey(), (List) values); - } - Map> unmodifiableMap = Collections.unmodifiableMap(result); - return toMultiValueMap(unmodifiableMap); - } - - - /** - * Iterator wrapping an Enumeration. - */ - private static class EnumerationIterator implements Iterator { - - private final Enumeration enumeration; - - public EnumerationIterator(Enumeration enumeration) { - this.enumeration = enumeration; - } - - @Override - public boolean hasNext() { - return this.enumeration.hasMoreElements(); - } - - @Override - public E next() { - return this.enumeration.nextElement(); - } - - @Override - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException("Not supported"); - } - } - - /** - * Adapts a Map to the MultiValueMap contract. - */ - private static class MultiValueMapAdapter implements MultiValueMap, Serializable { - - private final Map> mMap; - - public MultiValueMapAdapter(Map> map) { - Assert.notNull(map, "'map' must not be null"); - this.mMap = map; - } - - @Override - public void add(K key, V value) { - List values = this.mMap.get(key); - if (values == null) { - values = new LinkedList<>(); - this.mMap.put(key, values); - } - values.add(value); - } - - @Override - public V getFirst(K key) { - List values = this.mMap.get(key); - return (values != null ? values.get(0) : null); - } - - @Override - public void set(K key, V value) { - List values = new LinkedList<>(); - values.add(value); - this.mMap.put(key, values); - } - - @Override - public void setAll(Map values) { - for (Entry entry: values.entrySet()) { - set(entry.getKey(), entry.getValue()); - } - } - - @Override - public Map toSingleValueMap() { - LinkedHashMap singleValueMap = new LinkedHashMap<>(this.mMap.size()); - for (Entry> entry: mMap.entrySet()) { - singleValueMap.put(entry.getKey(), entry.getValue().get(0)); - } - return singleValueMap; - } - - @Override - public int size() { - return this.mMap.size(); - } - - @Override - public boolean isEmpty() { - return this.mMap.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return this.mMap.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return this.mMap.containsValue(value); - } - - @Override - public List get(Object key) { - return this.mMap.get(key); - } - - @Override - public List put(K key, List value) { - return this.mMap.put(key, value); - } - - @Override - public List remove(Object key) { - return this.mMap.remove(key); - } - - @Override - public void putAll(Map> map) { - this.mMap.putAll(map); - } - - @Override - public void clear() { - this.mMap.clear(); - } - - @Override - public Set keySet() { - return this.mMap.keySet(); - } - - @Override - public Collection> values() { - return this.mMap.values(); - } - - @Override - public Set>> entrySet() { - return this.mMap.entrySet(); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - return mMap.equals(other); - } - - @Override - public int hashCode() { - return this.mMap.hashCode(); - } - - @Override - public String toString() { - return this.mMap.toString(); - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java deleted file mode 100644 index 89cae7477aa4962ba0655ce94d32807c928422a1..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/DigestUtils.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -/** - * Created by Zhenjie Yan on 2018/9/6. - */ -public 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) throws UnsupportedEncodingException { - return md5Digest(string.getBytes("UTF-8")); - } - - /** - * 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) throws UnsupportedEncodingException { - return md5DigestAsHex(string.getBytes("UTF-8")); - } - - /** - * 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/api/src/main/java/com/yanzhenjie/andserver/util/Executors.java b/api/src/main/java/com/yanzhenjie/andserver/util/Executors.java deleted file mode 100644 index 72569f58b2f70e2d2fac2c36a4e1494fe9d724e3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/Executors.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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 ohos.eventhandler.EventHandler; -import ohos.eventhandler.EventRunner; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; - -/** - * Created by Zhenjie Yan on 2018/9/10. - */ -public 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 EventHandler mHandler; - - private Executors() { - mService = java.util.concurrent.Executors.newCachedThreadPool(); - mHandler = new EventHandler(EventRunner.getMainEventRunner()); - } - - /** - * 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.postTask(command); - } - - /** - * Delay post a runnable. - */ - public void postDelayed(Runnable command, long delayedMillis) { - mHandler.postTask(command, delayedMillis); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/HttpDateFormat.java b/api/src/main/java/com/yanzhenjie/andserver/util/HttpDateFormat.java deleted file mode 100644 index d53affe24608b380735f5c41d07672f6fa8c4645..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/HttpDateFormat.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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; - -/** - * Utility class to generate HTTP dates. - * - * @author Remy Maucherat - */ -public final class HttpDateFormat { - - /** - * The date format of the Http header. - */ - private static final String RFC1123_DATE = "EEE, dd MMM yyyy HH:mm:ss zzz"; - private static final SimpleDateFormat[] FORMATS_TEMPLATE = {new SimpleDateFormat(RFC1123_DATE, Locale.US), - new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), - new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)}; - - private static final TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT"); - private static final SimpleDateFormat FORMAT = new SimpleDateFormat(RFC1123_DATE, Locale.US); - - static { - FORMAT.setTimeZone(GMT_ZONE); - } - - /** - * Get the current date in HTTP format. - * - * @return the HTTP date. - */ - public static String getCurrentDate() { - synchronized (FORMAT) { - long now = System.currentTimeMillis(); - return FORMAT.format(new Date(now)); - } - } - - /** - * Get the HTTP format of the specified date. - * - * @param value the date. - * - * @return the HTTP date. - */ - public static String formatDate(long value) { - synchronized (HttpDateFormat.class) { - Date dateValue = new Date(value); - return FORMAT.format(dateValue); - } - } - - /** - * Try to parse the given date as a HTTP date. - * - * @param value the HTTP date. - * - * @return the date as a long. - */ - public static long parseDate(String value) { - Date date = null; - for (SimpleDateFormat format : FORMATS_TEMPLATE) { - try { - date = format.parse(value); - } catch (ParseException e) { - // Nothing. - } - } - - if (date == null) { - return -1L; - } - return date.getTime(); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/HttpHeaders.java b/api/src/main/java/com/yanzhenjie/andserver/util/HttpHeaders.java deleted file mode 100644 index ee91c1a87e832b919f272b89d928923801e68924..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/HttpHeaders.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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; - -/** - * Created by Zhenjie Yan on 2018/9/7. - * - * @deprecated use {@link com.yanzhenjie.andserver.http.HttpHeaders} instead. - */ -@Deprecated -public interface HttpHeaders extends com.yanzhenjie.andserver.http.HttpHeaders { -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/IOUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/IOUtils.java deleted file mode 100644 index 9065b782223928b9934f5bf8401a7a47f6226d2f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/IOUtils.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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 com.yanzhenjie.andserver.http.RequestBody; -import ohos.data.usage.StatVfs; -import ohos.system.version.SystemVersion; - -import java.io.*; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; - -/** - * Created in 2016/4/12 21:21. - */ -public class IOUtils { - - private static final byte[] EMPTY_CONTENT = new byte[0]; - - public static void closeQuietly(Closeable closeable) { - if (closeable != null) { - try { - closeable.close(); - } catch (Exception ignored) { - } - } - - RequestBody requestBody; - } - - public static void flushQuietly(Flushable flushable) { - if (flushable != null) { - try { - flushable.flush(); - } catch (Exception ignored) { - } - } - } - - public static BufferedInputStream toBufferedInputStream(InputStream inputStream) { - return inputStream instanceof BufferedInputStream - ? (BufferedInputStream) inputStream - : new BufferedInputStream(inputStream); - } - - public static BufferedOutputStream toBufferedOutputStream(OutputStream outputStream) { - return outputStream instanceof BufferedOutputStream - ? (BufferedOutputStream) outputStream - : new BufferedOutputStream(outputStream); - } - - public static BufferedReader toBufferedReader(Reader reader) { - return reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); - } - - public static BufferedWriter toBufferedWriter(Writer writer) { - return writer instanceof BufferedWriter ? (BufferedWriter) writer : new BufferedWriter(writer); - } - - public static InputStream toInputStream(CharSequence input) throws UnsupportedEncodingException { - return new ByteArrayInputStream(input.toString().getBytes("UTF-8")); - } - - public static InputStream toInputStream(CharSequence input, String charset) { - return toInputStream(input, Charset.forName(charset)); - } - - public static InputStream toInputStream(CharSequence input, Charset charset) { - byte[] bytes = input.toString().getBytes(charset); - return new ByteArrayInputStream(bytes); - } - - public static InputStream createEmptyInput() { - return new ByteArrayInputStream(EMPTY_CONTENT); - } - - public static InputStream toNonClosing(InputStream in) { - Assert.notNull(in, "No InputStream specified"); - return new NonClosingInputStream(in); - } - - public static OutputStream toNonClosing(OutputStream out) { - Assert.notNull(out, "No OutputStream specified."); - return new NonClosingOutputStream(out); - } - - public static String toString(InputStream input) throws IOException { - return new String(toByteArray(input),"UTF-8"); - } - - public static String toString(InputStream input, String charset) throws IOException { - return new String(toByteArray(input), charset); - } - - public static String toString(InputStream input, Charset charset) throws IOException { - return new String(toByteArray(input), charset); - } - - public static String toString(Reader input) throws IOException { - return new String(toByteArray(input),"UTF-8"); - } - - public static String toString(Reader input, String charset) throws IOException { - return new String(toByteArray(input), charset); - } - - public static String toString(Reader input, Charset charset) throws IOException { - return new String(toByteArray(input), charset); - } - - public static String toString(byte[] byteArray) throws UnsupportedEncodingException { - return new String(byteArray,"UTF-8"); - } - - public static String toString(byte[] byteArray, String charset) { - return toString(byteArray, Charset.forName(charset)); - } - - public static String toString(byte[] byteArray, Charset charset) { - return new String(byteArray, charset); - } - - public static byte[] toByteArray(CharSequence input) throws UnsupportedEncodingException { - if (input == null) { - return new byte[0]; - } - return input.toString().getBytes("UTF-8"); - } - - public static byte[] toByteArray(CharSequence input, String charset) { - return toByteArray(input, Charset.forName(charset)); - } - - public static byte[] toByteArray(CharSequence input, Charset charset) { - if (input == null) { - return new byte[0]; - } else { - return input.toString().getBytes(charset); - } - } - - public static byte[] toByteArray(InputStream input) throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - write(input, output); - output.close(); - return output.toByteArray(); - } - - public static byte[] toByteArray(InputStream input, int size) throws IOException { - if (size < 0) { - throw new IllegalArgumentException("Size must be equal or greater than zero: " + size); - } - - if (size == 0) { - return new byte[0]; - } - - byte[] data = new byte[size]; - int offset = 0; - int byteCount; - while ((offset < size) && (byteCount = input.read(data, offset, size - offset)) != -1) { - offset += byteCount; - } - - if (offset != size) { - throw new IOException("Unexpected byte count size. current: " + offset + ", excepted: " + size); - } - return data; - } - - public static byte[] toByteArray(Reader input) throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - write(input, output); - output.close(); - return output.toByteArray(); - } - - public static byte[] toByteArray(Reader input, String charset) throws IOException { - return toByteArray(input, Charset.forName(charset)); - } - - public static byte[] toByteArray(Reader input, Charset charset) throws IOException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - write(input, output, charset); - output.close(); - return output.toByteArray(); - } - - public static char[] toCharArray(CharSequence input) throws IOException { - CharArrayWriter output = new CharArrayWriter(); - write(output, input); - return output.toCharArray(); - } - - public static char[] toCharArray(InputStream input) throws IOException { - CharArrayWriter output = new CharArrayWriter(); - write(input, output); - return output.toCharArray(); - } - - public static char[] toCharArray(InputStream input, String charset) throws IOException { - return toCharArray(input, Charset.forName(charset)); - } - - public static char[] toCharArray(InputStream input, Charset charset) throws IOException { - CharArrayWriter output = new CharArrayWriter(); - write(input, output, charset); - return output.toCharArray(); - } - - public static char[] toCharArray(Reader input) throws IOException { - CharArrayWriter output = new CharArrayWriter(); - write(input, output); - return output.toCharArray(); - } - - public static List readLines(InputStream input, String charset) throws IOException { - return readLines(input, Charset.forName(charset)); - } - - public static List readLines(InputStream input, Charset charset) throws IOException { - Reader reader = new InputStreamReader(input, charset); - return readLines(reader); - } - - public static List readLines(InputStream input) throws IOException { - Reader reader = new InputStreamReader(input,"UTF-8"); - return readLines(reader); - } - - public static List readLines(Reader input) throws IOException { - BufferedReader reader = toBufferedReader(input); - List list = new ArrayList<>(); - String line = reader.readLine(); - while (line != null) { - list.add(line); - line = reader.readLine(); - } - return list; - } - - public static void write(OutputStream output, byte[] data) throws IOException { - if (data != null) { - output.write(data); - output.flush(); - } - } - - public static void write(Writer output, byte[] data) throws IOException { - if (data != null) { - output.write(new String(data,"UTF-8")); - output.flush(); - } - } - - public static void write(Writer output, byte[] data, String charset) throws IOException { - write(output, data, Charset.forName(charset)); - } - - public static void write(Writer output, byte[] data, Charset charset) throws IOException { - if (data != null) { - output.write(new String(data, charset)); - output.flush(); - } - } - - public static void write(Writer output, char[] data) throws IOException { - if (data != null) { - output.write(data); - output.flush(); - } - } - - public static void write(OutputStream output, char[] data) throws IOException { - if (data != null) { - output.write(new String(data).getBytes("UTF-8")); - output.flush(); - } - } - - public static void write(OutputStream output, char[] data, String charset) throws IOException { - write(output, data, Charset.forName(charset)); - } - - public static void write(OutputStream output, char[] data, Charset charset) throws IOException { - if (data != null) { - output.write(new String(data).getBytes(charset)); - output.flush(); - } - } - - public static void write(Writer output, CharSequence data) throws IOException { - if (data != null) { - output.write(data.toString()); - output.flush(); - } - } - - public static void write(OutputStream output, CharSequence data) throws IOException { - if (data != null) { - output.write(data.toString().getBytes("UTF-8")); - output.flush(); - } - } - - public static void write(OutputStream output, CharSequence data, String charset) throws IOException { - write(output, data, Charset.forName(charset)); - } - - public static void write(OutputStream output, CharSequence data, Charset charset) throws IOException { - if (data != null) { - output.write(data.toString().getBytes(charset)); - output.flush(); - } - } - - public static void write(Reader input, OutputStream output) throws IOException { - Writer out = new OutputStreamWriter(output,"UTF-8"); - write(input, out); - } - - public static void write(InputStream input, OutputStream output) throws IOException { - int len; - byte[] buffer = new byte[4096]; - while ((len = input.read(buffer)) != -1) { - output.write(buffer, 0, len); - output.flush(); - } - } - - public static void write(InputStream input, Writer output) throws IOException { - Reader in = new InputStreamReader(input,"UTF-8"); - write(in, output); - } - - public static void write(Reader input, OutputStream output, String charset) throws IOException { - write(input, output, Charset.forName(charset)); - } - - public static void write(Reader input, OutputStream output, Charset charset) throws IOException { - Writer out = new OutputStreamWriter(output, charset); - write(input, out); - } - - public static void write(InputStream input, OutputStream output, String charset) throws IOException { - write(input, output, Charset.forName(charset)); - } - - public static void write(InputStream input, OutputStream output, Charset charset) throws IOException { - Reader in = new InputStreamReader(input, charset); - write(in, output); - } - - public static void write(InputStream input, Writer output, String charset) throws IOException { - write(input, output, Charset.forName(charset)); - } - - public static void write(InputStream input, Writer output, Charset charset) throws IOException { - Reader in = new InputStreamReader(input, charset); - write(in, output); - } - - public static void write(Reader input, Writer output) throws IOException { - int len; - char[] buffer = new char[4096]; - while (-1 != (len = input.read(buffer))) { - output.write(buffer, 0, len); - output.flush(); - } - } - - public static boolean contentEquals(InputStream input1, InputStream input2) throws IOException { - input1 = toBufferedInputStream(input1); - input2 = toBufferedInputStream(input2); - - int ch = input1.read(); - while (-1 != ch) { - int ch2 = input2.read(); - if (ch != ch2) { - return false; - } - ch = input1.read(); - } - int ch2 = input2.read(); - return ch2 == -1; - } - - public static boolean contentEquals(Reader input1, Reader input2) throws IOException { - input1 = toBufferedReader(input1); - input2 = toBufferedReader(input2); - - int ch = input1.read(); - while (-1 != ch) { - int ch2 = input2.read(); - if (ch != ch2) { - return false; - } - ch = input1.read(); - } - - int ch2 = input2.read(); - return ch2 == -1; - } - - public static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2) throws IOException { - BufferedReader br1 = toBufferedReader(input1); - BufferedReader br2 = toBufferedReader(input2); - - String line1 = br1.readLine(); - String line2 = br2.readLine(); - while ((line1 != null) && (line2 != null) && (line1.equals(line2))) { - line1 = br1.readLine(); - line2 = br2.readLine(); - } - return line1 != null && (line2 == null || line1.equals(line2)); - } - - /** - * Access to a directory available size. - * - * @param path path. - * - * @return space size. - */ - public static long getDirSize(String path) { - StatVfs stat; - try { - stat = new StatVfs(path); - } catch (Exception e) { - return 0; - } - if (SystemVersion.getBuildVersion() >= 18) { - return stat.getFreeSpace() * stat.getAvailableSpace(); - } else { - return (long) stat.getFreeSpace() * (long) stat.getAvailableSpace(); - } - } - - /** - * If the folder can be written. - * - * @param path path. - * - * @return True: success, or false: failure. - */ - public static boolean canWrite(String path) { - return new File(path).canWrite(); - } - - /** - * If the folder can be readResponse. - * - * @param path path. - * - * @return True: success, or false: failure. - */ - public static boolean canRead(String path) { - return new File(path).canRead(); - } - - /** - * Create a folder, If the folder exists is not created. - * - * @param folderPath folder path. - * - * @return True: success, or false: failure. - */ - public static boolean createFolder(String folderPath) { - if (!folderPath.isEmpty()) { - File folder = new File(folderPath); - return createFolder(folder); - } - return false; - } - - /** - * Create a folder, If the folder exists is not created. - * - * @param targetFolder folder path. - * - * @return True: success, or false: failure. - */ - public static boolean createFolder(File targetFolder) { - if (targetFolder.exists()) { - if (targetFolder.isDirectory()) { - return true; - } - //noinspection ResultOfMethodCallIgnored - targetFolder.delete(); - } - return targetFolder.mkdirs(); - } - - /** - * Create a folder, If the folder exists is not created. - * - * @param folderPath folder path. - * - * @return True: success, or false: failure. - */ - public static boolean createNewFolder(String folderPath) { - return delFileOrFolder(folderPath) && createFolder(folderPath); - } - - /** - * Create a folder, If the folder exists is not created. - * - * @param targetFolder folder path. - * - * @return True: success, or false: failure. - */ - public static boolean createNewFolder(File targetFolder) { - return delFileOrFolder(targetFolder) && createFolder(targetFolder); - } - - /** - * Create a file, If the file exists is not created. - * - * @param filePath file path. - * - * @return True: success, or false: failure. - */ - public static boolean createFile(String filePath) { - if (!filePath.isEmpty()) { - File file = new File(filePath); - return createFile(file); - } - return false; - } - - /** - * Create a file, If the file exists is not created. - * - * @param targetFile file. - * - * @return True: success, or false: failure. - */ - public static boolean createFile(File targetFile) { - if (targetFile.exists()) { - if (targetFile.isFile()) { - return true; - } - delFileOrFolder(targetFile); - } - try { - return targetFile.createNewFile(); - } catch (IOException e) { - return false; - } - } - - /** - * Create a new file, if the file exists, delete and create again. - * - * @param filePath file path. - * - * @return True: success, or false: failure. - */ - public static boolean createNewFile(String filePath) { - if (!filePath.isEmpty()) { - File file = new File(filePath); - return createNewFile(file); - } - return false; - } - - /** - * Create a new file, if the file exists, delete and create again. - * - * @param targetFile file. - * - * @return True: success, or false: failure. - */ - public static boolean createNewFile(File targetFile) { - if (targetFile.exists()) { - delFileOrFolder(targetFile); - } - try { - return targetFile.createNewFile(); - } catch (IOException e) { - return false; - } - } - - /** - * Delete file or folder. - * - * @param path path. - * - * @return is succeed. - * - * @see #delFileOrFolder(File) - */ - public static boolean delFileOrFolder(String path) { - return delFileOrFolder(new File(path)); - } - - /** - * Delete file or folder. - * - * @param file file. - * - * @return is succeed. - * - * @see #delFileOrFolder(String) - */ - public static boolean delFileOrFolder(File file) { - if (file == null || !file.exists()) { - // do nothing - } else if (file.isFile()) { - file.delete(); - } else if (file.isDirectory()) { - File[] files = file.listFiles(); - if (files != null) { - for (File sonFile: files) { - delFileOrFolder(sonFile); - } - } - file.delete(); - } - return true; - } - - private static class NonClosingInputStream extends FilterInputStream { - - public NonClosingInputStream(InputStream in) { - super(in); - } - - @Override - public void close() throws IOException { - } - } - - private static class NonClosingOutputStream extends FilterOutputStream { - - public NonClosingOutputStream(OutputStream out) { - super(out); - } - - @Override - public void write(byte[] b, int off, int let) throws IOException { - // It is critical that we override this method for performance. - out.write(b, off, let); - } - - @Override - public void close() throws IOException { - } - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/LinkedCaseInsensitiveMap.java b/api/src/main/java/com/yanzhenjie/andserver/util/LinkedCaseInsensitiveMap.java deleted file mode 100644 index 86ef7282a57d6e4547837878ee41e0b04e1e4ba8..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/LinkedCaseInsensitiveMap.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.Serializable; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/6/29. - */ -public class LinkedCaseInsensitiveMap implements Map, Serializable, Cloneable { - - private final LinkedHashMap mSource; - private final HashMap mCaseInsensitiveKeys; - private final Locale mLocale; - - /** - * Create a new instance that stores case-insensitive keys according to the default mLocale, by default in lower - * case. - */ - public LinkedCaseInsensitiveMap() { - this((Locale) null); - } - - /** - * Create a new instance that stores case-insensitive keys according to the given mLocale, by default in lower - * case. - * - * @param locale the {@link Locale} to use for case-insensitive key conversion. - */ - public LinkedCaseInsensitiveMap(Locale locale) { - this(16, locale); - } - - /** - * Create a new instance that wraps a {@link LinkedHashMap} with the given initial capacity and stores - * case-insensitive keys according to the default mLocale, by default in lower case. - * - * @param initialCapacity the initial capacity. - */ - public LinkedCaseInsensitiveMap(int initialCapacity) { - this(initialCapacity, null); - } - - /** - * Create a new instance that wraps a {@link LinkedHashMap} with the given initial capacity and stores - * case-insensitive keys according to the given mLocale, by default in lower case. - * - * @param initialCapacity the initial capacity. - * @param locale the mLocale to use for case-insensitive key conversion. - */ - public LinkedCaseInsensitiveMap(int initialCapacity, Locale locale) { - this.mSource = new LinkedHashMap(initialCapacity) { - @Override - public boolean containsKey(Object key) { - return LinkedCaseInsensitiveMap.this.containsKey(key); - } - - @Override - protected boolean removeEldestEntry(Entry eldest) { - boolean isRemoved = LinkedCaseInsensitiveMap.this.removeEldestEntry(eldest); - if (isRemoved) { - mCaseInsensitiveKeys.remove(convertKey(eldest.getKey())); - } - return isRemoved; - } - }; - this.mCaseInsensitiveKeys = new HashMap<>(initialCapacity); - this.mLocale = (locale != null ? locale : Locale.getDefault()); - } - - @SuppressWarnings("unchecked") - private LinkedCaseInsensitiveMap(LinkedCaseInsensitiveMap other) { - this.mSource = (LinkedHashMap) other.mSource.clone(); - this.mCaseInsensitiveKeys = (HashMap) other.mCaseInsensitiveKeys.clone(); - this.mLocale = other.mLocale; // No need to clone. - } - - - @Override - public int size() { - return this.mSource.size(); - } - - @Override - public boolean isEmpty() { - return this.mSource.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return (key instanceof String && this.mCaseInsensitiveKeys.containsKey(convertKey((String) key))); - } - - @Override - public boolean containsValue(Object value) { - return this.mSource.containsValue(value); - } - - @Override - public V get(Object key) { - if (key instanceof String) { - String caseInsensitiveKey = this.mCaseInsensitiveKeys.get(convertKey((String) key)); - if (caseInsensitiveKey != null) { - return this.mSource.get(caseInsensitiveKey); - } - } - return null; - } - - @Override - public V getOrDefault(Object key, V defaultValue) { - if (key instanceof String) { - String caseInsensitiveKey = this.mCaseInsensitiveKeys.get(convertKey((String) key)); - if (caseInsensitiveKey != null) { - return this.mSource.get(caseInsensitiveKey); - } - } - return defaultValue; - } - - @Override - public V put(String key, V value) { - String oldKey = this.mCaseInsensitiveKeys.put(convertKey(key), key); - if (oldKey != null && !oldKey.equals(key)) { - this.mSource.remove(oldKey); - } - return this.mSource.put(key, value); - } - - @Override - public void putAll( Map map) { - if (map.isEmpty()) { - return; - } - - for (Entry entry : map.entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @Override - public V remove(Object key) { - if (key instanceof String) { - String caseInsensitiveKey = this.mCaseInsensitiveKeys.remove(convertKey((String) key)); - if (caseInsensitiveKey != null) { - return this.mSource.remove(caseInsensitiveKey); - } - } - return null; - } - - @Override - public void clear() { - this.mCaseInsensitiveKeys.clear(); - this.mSource.clear(); - } - - - @Override - public Set keySet() { - return this.mSource.keySet(); - } - - - @Override - public Collection values() { - return this.mSource.values(); - } - - - @Override - public Set> entrySet() { - return this.mSource.entrySet(); - } - - @Override - public LinkedCaseInsensitiveMap clone() { - return new LinkedCaseInsensitiveMap<>(this); - } - - @Override - public boolean equals(Object obj) { - return this.mSource.equals(obj); - } - - @Override - public int hashCode() { - return this.mSource.hashCode(); - } - - @Override - public String toString() { - return this.mSource.toString(); - } - - - /** - * Return the locale used by this {@code LinkedCaseInsensitiveMap}. Used for case-insensitive key conversion. - * - * @see #LinkedCaseInsensitiveMap(Locale) - * @see #convertKey(String) - */ - public Locale getLocale() { - return this.mLocale; - } - - /** - * Convert the given key to a case-insensitive key. - * - *

The default implementation converts the key to lower-case according to this map's locale. - * - * @param key the user-specified key. - * - * @return the key to use for string. - * - * @see String#toLowerCase(Locale) - */ - protected String convertKey(String key) { - return key.toLowerCase(getLocale()); - } - - /** - * Determine whether this map should remove the given eldest entry. - * - * @param eldest the candidate entry. - * - * @return true for removing it, false for keeping it. - * - * @see LinkedHashMap#removeEldestEntry(Entry) - */ - protected boolean removeEldestEntry(Entry eldest) { - return false; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/LinkedMultiValueMap.java b/api/src/main/java/com/yanzhenjie/andserver/util/LinkedMultiValueMap.java deleted file mode 100644 index 617cb7af044938146609d9469cddb36f5715278c..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/LinkedMultiValueMap.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.util.*; - -/** - * Created by Zhenjie Yan on 2018/6/21. - */ -public class LinkedMultiValueMap implements MultiValueMap, Cloneable { - - private final Map> mSource; - - public LinkedMultiValueMap() { - mSource = new LinkedHashMap<>(); - } - - public LinkedMultiValueMap(int initialCapacity) { - mSource = new LinkedHashMap<>(initialCapacity); - } - - public LinkedMultiValueMap(Map> otherMap) { - mSource = new LinkedHashMap<>(otherMap); - } - - @Override - public void add(K key, V value) { - List values = mSource.get(key); - if (values == null) { - values = new LinkedList<>(); - mSource.put(key, values); - } - values.add(value); - } - - @Override - public V getFirst(K key) { - List values = mSource.get(key); - return (values != null ? values.get(0) : null); - } - - @Override - public void set(K key, V value) { - List values = new LinkedList<>(); - values.add(value); - this.mSource.put(key, values); - } - - @Override - public void setAll(Map values) { - for (Map.Entry entry : values.entrySet()) { - set(entry.getKey(), entry.getValue()); - } - } - - @Override - public Map toSingleValueMap() { - LinkedHashMap singleValueMap = new LinkedHashMap<>(mSource.size()); - for (Map.Entry> entry : mSource.entrySet()) { - singleValueMap.put(entry.getKey(), entry.getValue().get(0)); - } - return singleValueMap; - } - - @Override - public int size() { - return mSource.size(); - } - - @Override - public boolean isEmpty() { - return mSource.isEmpty(); - } - - @Override - public boolean containsKey(Object key) { - return mSource.containsKey(key); - } - - @Override - public boolean containsValue(Object value) { - return mSource.containsValue(value); - } - - @Override - public List get(Object key) { - return mSource.get(key); - } - - @Override - public List put(K key, List value) { - return mSource.put(key, value); - } - - @Override - public List remove(Object key) { - return mSource.remove(key); - } - - @Override - public void putAll(Map> map) { - mSource.putAll(map); - } - - @Override - public void clear() { - mSource.clear(); - } - - @Override - public Set keySet() { - return mSource.keySet(); - } - - @Override - public Collection> values() { - return mSource.values(); - } - - @Override - public Set>> entrySet() { - return mSource.entrySet(); - } - - @Override - public LinkedMultiValueMap clone() { - return new LinkedMultiValueMap<>(this); - } - - @Override - public boolean equals(Object obj) { - return mSource.equals(obj); - } - - @Override - public int hashCode() { - return mSource.hashCode(); - } - - @Override - public String toString() { - return mSource.toString(); - } - - public LinkedMultiValueMap deepCopy() { - LinkedMultiValueMap copy = new LinkedMultiValueMap<>(mSource.size()); - for (Map.Entry> entry : mSource.entrySet()) { - copy.put(entry.getKey(), new LinkedList<>(entry.getValue())); - } - return copy; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/MediaType.java b/api/src/main/java/com/yanzhenjie/andserver/util/MediaType.java deleted file mode 100644 index 1e2787651629def6ee440d4a672b02485992bb6a..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/MediaType.java +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.yanzhenjie.andserver.error.InvalidMediaTypeException; -import com.yanzhenjie.andserver.error.InvalidMimeTypeException; -import com.yanzhenjie.andserver.util.comparator.CompoundComparator; - -import java.io.Serializable; -import java.nio.charset.Charset; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/6/27. - */ -public class MediaType extends MimeType implements Serializable { - - /** - * Public constant media type that includes all media ranges (i.e. "*/*"). - */ - public static final MediaType ALL; - - /** - * A String equivalent of {@code MediaType#ALL}. - */ - public static final String ALL_VALUE = "*/*"; - - /** - * Public constant media type for {@code application/json}. - * - * @see #APPLICATION_JSON_UTF8 - */ - public final static MediaType APPLICATION_JSON; - - /** - * A String equivalent of {@code MediaType#APPLICATION_JSON}. - * - * @see #APPLICATION_JSON_UTF8_VALUE - */ - public final static String APPLICATION_JSON_VALUE = "application/json"; - - /** - * Public constant media type for {@code application/json;charset=UTF-8}. - */ - public final static MediaType APPLICATION_JSON_UTF8; - - /** - * A String equivalent of {@link MediaType#APPLICATION_JSON_UTF8}. - */ - public final static String APPLICATION_JSON_UTF8_VALUE = APPLICATION_JSON_VALUE + ";charset=UTF-8"; - /** - * Public constant media type for {@code application/xml}. - */ - public final static MediaType APPLICATION_XML; - - /** - * A String equivalent of {@link MediaType#APPLICATION_XML}. - */ - public final static String APPLICATION_XML_VALUE = "application/xml"; - - /** - * Public constant media type for {@code application/xml}. - */ - public final static MediaType APPLICATION_XML_UTF8; - - /** - * A String equivalent of {@link MediaType#APPLICATION_XML}. - */ - public final static String APPLICATION_XML_UTF8_VALUE = APPLICATION_XML_VALUE + ";charset=UTF-8"; - - /** - * Public constant media type for {@code application/atom+xml}. - */ - public final static MediaType APPLICATION_ATOM_XML; - - /** - * A String equivalent of {@link MediaType#APPLICATION_ATOM_XML}. - */ - public final static String APPLICATION_ATOM_XML_VALUE = "application/atom+xml"; - - /** - * Public constant media type for {@code application/x-www-form-urlencoded}. - */ - public final static MediaType APPLICATION_FORM_URLENCODED; - - /** - * A String equivalent of {@link MediaType#APPLICATION_FORM_URLENCODED}. - */ - public final static String APPLICATION_FORM_URLENCODED_VALUE = "application/x-www-form-urlencoded"; - - /** - * Public constant media type for {@code application/octet-stream}. - */ - public final static MediaType APPLICATION_OCTET_STREAM; - - /** - * A String equivalent of {@link MediaType#APPLICATION_OCTET_STREAM}. - */ - public final static String APPLICATION_OCTET_STREAM_VALUE = "application/octet-stream"; - - /** - * Public constant media type for {@code application/rss+xml}. - */ - public final static MediaType APPLICATION_RSS_XML; - - /** - * A String equivalent of {@link MediaType#APPLICATION_RSS_XML}. - */ - public final static String APPLICATION_RSS_XML_VALUE = "application/rss+xml"; - - /** - * Public constant media type for {@code application/xhtml+xml}. - */ - public final static MediaType APPLICATION_XHTML_XML; - - /** - * A String equivalent of {@link MediaType#APPLICATION_XHTML_XML}. - */ - public final static String APPLICATION_XHTML_XML_VALUE = "application/xhtml+xml"; - - /** - * Public constant media type for {@code application/pdf}. - */ - public final static MediaType APPLICATION_PDF; - - /** - * A String equivalent of {@link MediaType#APPLICATION_PDF}. - */ - public final static String APPLICATION_PDF_VALUE = "application/pdf"; - - /** - * Public constant media type for {@code image/gif}. - */ - public final static MediaType IMAGE_GIF; - - /** - * A String equivalent of {@link MediaType#IMAGE_GIF}. - */ - public final static String IMAGE_GIF_VALUE = "image/gif"; - - /** - * Public constant media type for {@code image/jpeg}. - */ - public final static MediaType IMAGE_JPEG; - - /** - * A String equivalent of {@link MediaType#IMAGE_JPEG}. - */ - public final static String IMAGE_JPEG_VALUE = "image/jpeg"; - - /** - * Public constant media type for {@code image/png}. - */ - public final static MediaType IMAGE_PNG; - - /** - * A String equivalent of {@link MediaType#IMAGE_PNG}. - */ - public final static String IMAGE_PNG_VALUE = "image/png"; - - /** - * Public constant media type for {@code multipart/form-data}. - */ - public final static MediaType MULTIPART_FORM_DATA; - - /** - * A String equivalent of {@link MediaType#MULTIPART_FORM_DATA}. - */ - public final static String MULTIPART_FORM_DATA_VALUE = "multipart/form-data"; - - /** - * Public constant media type for {@code text/event-stream}. - * - * @see Server-Sent Events W3C recommendation - */ - public final static MediaType TEXT_EVENT_STREAM; - - /** - * A String equivalent of {@link MediaType#TEXT_EVENT_STREAM}. - */ - public final static String TEXT_EVENT_STREAM_VALUE = "text/event-stream"; - - /** - * Public constant media type for {@code text/html}. - */ - public final static MediaType TEXT_HTML; - - /** - * A String equivalent of {@link MediaType#TEXT_HTML}. - */ - public final static String TEXT_HTML_VALUE = "text/html"; - - /** - * Public constant media type for {@code text/markdown}. - */ - public final static MediaType TEXT_MARKDOWN; - - /** - * A String equivalent of {@link MediaType#TEXT_MARKDOWN}. - */ - public final static String TEXT_MARKDOWN_VALUE = "text/markdown"; - - /** - * Public constant media type for {@code text/plain}. - */ - public final static MediaType TEXT_PLAIN; - - /** - * A String equivalent of {@link MediaType#TEXT_PLAIN}. - */ - public final static String TEXT_PLAIN_VALUE = "text/plain"; - - /** - * Public constant media type for {@code text/xml}. - */ - public final static MediaType TEXT_XML; - - /** - * A String equivalent of {@link MediaType#TEXT_XML}. - */ - public final static String TEXT_XML_VALUE = "text/xml"; - - private static final String PARAM_QUALITY_FACTOR = "q"; - - static { - ALL = valueOf(ALL_VALUE); - APPLICATION_JSON = valueOf(APPLICATION_JSON_VALUE); - APPLICATION_JSON_UTF8 = valueOf(APPLICATION_JSON_UTF8_VALUE); - APPLICATION_XML = valueOf(APPLICATION_XML_VALUE); - APPLICATION_XML_UTF8 = valueOf(APPLICATION_XML_UTF8_VALUE); - APPLICATION_ATOM_XML = valueOf(APPLICATION_ATOM_XML_VALUE); - APPLICATION_FORM_URLENCODED = valueOf(APPLICATION_FORM_URLENCODED_VALUE); - APPLICATION_OCTET_STREAM = valueOf(APPLICATION_OCTET_STREAM_VALUE); - APPLICATION_RSS_XML = valueOf(APPLICATION_RSS_XML_VALUE); - APPLICATION_XHTML_XML = valueOf(APPLICATION_XHTML_XML_VALUE); - APPLICATION_PDF = valueOf(APPLICATION_PDF_VALUE); - IMAGE_GIF = valueOf(IMAGE_GIF_VALUE); - IMAGE_JPEG = valueOf(IMAGE_JPEG_VALUE); - IMAGE_PNG = valueOf(IMAGE_PNG_VALUE); - MULTIPART_FORM_DATA = valueOf(MULTIPART_FORM_DATA_VALUE); - TEXT_EVENT_STREAM = valueOf(TEXT_EVENT_STREAM_VALUE); - TEXT_HTML = valueOf(TEXT_HTML_VALUE); - TEXT_MARKDOWN = valueOf(TEXT_MARKDOWN_VALUE); - TEXT_PLAIN = valueOf(TEXT_PLAIN_VALUE); - TEXT_XML = valueOf(TEXT_XML_VALUE); - } - - /** - * Create a new {@code MediaType} for the given primary type.

The {@linkplain #getSubtype() subtype} is set to - * "*", parameters empty. - * - * @param type the primary type. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(String type) { - super(type); - } - - /** - * Create a new {@code MediaType} for the given primary type and subtype. - * - *

The parameters are empty. - * - * @param type the primary type. - * @param subtype the subtype. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(String type, String subtype) { - super(type, subtype, Collections.emptyMap()); - } - - /** - * Create a new {@code MediaType} for the given type, subtype, and character set. - * - * @param type the primary type. - * @param subtype the subtype. - * @param charset the character set. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(String type, String subtype, Charset charset) { - super(type, subtype, charset); - } - - /** - * Create a new {@code MediaType} for the given type, subtype, and quality value. - * - * @param type the primary type. - * @param subtype the subtype. - * @param qualityValue the quality value. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(String type, String subtype, double qualityValue) { - this(type, subtype, Collections.singletonMap(PARAM_QUALITY_FACTOR, Double.toString(qualityValue))); - } - - /** - * Copy-constructor that copies the type, subtype and parameters of the given {@code MediaType}, and allows to set - * the specified character set. - * - * @param other the other media type. - * @param charset the character set. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(MediaType other, Charset charset) { - super(other, charset); - } - - /** - * Copy-constructor that copies the type and subtype of the given {@code MediaType}, and allows for different - * parameter. - * - * @param other the other media type. - * @param parameters the parameters, may be null. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(MediaType other, Map parameters) { - super(other.getType(), other.getSubtype(), parameters); - } - - /** - * Create a new {@code MediaType} for the given type, subtype, and parameters. - * - * @param type the primary type. - * @param subtype the subtype. - * @param parameters the parameters, may be null. - * - * @throws IllegalArgumentException if any of the parameters contain illegal characters. - */ - public MediaType(String type, String subtype, Map parameters) { - super(type, subtype, parameters); - } - - @Override - protected void checkParameters(String attribute, String value) { - super.checkParameters(attribute, value); - if (PARAM_QUALITY_FACTOR.equals(attribute)) { - value = unquote(value); - double d = Double.parseDouble(value); - String message = "Invalid quality value '" + value + "': should be between 0.0 and 1.0"; - Assert.isTrue(d >= 0D && d <= 1D, message); - } - } - - /** - * Return the quality value, as indicated by a {@code q} parameter, if any. Defaults to {@code 1.0}. - * - * @return the quality factory. - */ - public double getQualityValue() { - String qualityFactory = getParameter(PARAM_QUALITY_FACTOR); - return (qualityFactory != null ? Double.parseDouble(unquote(qualityFactory)) : 1D); - } - - /** - * Indicate whether this {@code MediaType} includes the given media type. - * - *

For instance, {@code text/*} includes {@code text/plain} and {@code text/html}, and {@code application/*+xml} - * includes {@code application/soap+xml}, etc. This method is not symmetric. - * - * @param other the reference media type with which to compare. - * - * @return {@code true} if this media type includes the given media type; {@code false} otherwise. - */ - public boolean includes(MediaType other) { - return super.includes(other); - } - - /** - * Indicate whether this {@code MediaType} is compatible with the given media type. - * - *

For instance, {@code text/*} is compatible with {@code text/plain}, {@code text/html}, and vice versa. In - * effect, this method is similar to {@link #includes(MediaType)}, except that it is symmetric. - * - * @param other the reference media type with which to compare. - * - * @return {@code true} if this media type is compatible with the given media type; {@code false} otherwise. - */ - public boolean isCompatibleWith(MediaType other) { - return super.isCompatibleWith(other); - } - - /** - * Return a replica of this instance with the quality value of the given MediaType. - * - * @return the same instance if the given MediaType doesn't have a quality value, or a new one otherwise. - */ - public MediaType copyQualityValue(MediaType mediaType) { - if (!mediaType.getParameters().containsKey(PARAM_QUALITY_FACTOR)) { - return this; - } - Map params = new LinkedHashMap<>(getParameters()); - params.put(PARAM_QUALITY_FACTOR, mediaType.getParameters().get(PARAM_QUALITY_FACTOR)); - return new MediaType(this, params); - } - - /** - * Return a replica of this instance with its quality value removed. - * - * @return the same instance if the media type doesn't contain a quality value, or a new one otherwise. - */ - public MediaType removeQualityValue() { - if (!getParameters().containsKey(PARAM_QUALITY_FACTOR)) { - return this; - } - Map params = new LinkedHashMap<>(getParameters()); - params.remove(PARAM_QUALITY_FACTOR); - return new MediaType(this, params); - } - - - /** - * Parse the given String value into a {@code MediaType} object, with this method name following the 'valueOf' - * naming convention. - * - * @param value the string to parse. - * - * @throws InvalidMediaTypeException if the media type value cannot be parsed. - * @see #parseMediaType(String) - */ - public static MediaType valueOf(String value) { - return parseMediaType(value); - } - - /** - * Parse the given String into a single {@code MediaType}. - * - * @param mediaType the string to parse. - * - * @return the media type. - * - * @throws InvalidMediaTypeException if the media type value cannot be parsed. - */ - public static MediaType parseMediaType(String mediaType) { - MimeType type; - try { - type = MimeType.valueOf(mediaType); - } catch (InvalidMimeTypeException ex) { - throw new InvalidMediaTypeException(ex); - } - try { - return new MediaType(type.getType(), type.getSubtype(), type.getParameters()); - } catch (IllegalArgumentException ex) { - throw new InvalidMediaTypeException(mediaType, ex.getMessage()); - } - } - - /** - * Parse the given comma-separated string into a list of {@code MediaType} objects. - * - *

This method can be used to parse an Accept or Content-Type header. - * - * @param mediaTypes the string to parse. - * - * @return the list of media types. - * - * @throws InvalidMediaTypeException if the media type value cannot be parsed. - */ - public static List parseMediaTypes(String mediaTypes) { - if (mediaTypes.isEmpty()) { - return Collections.emptyList(); - } - - StringTokenizer st = new StringTokenizer(mediaTypes, ","); - List tokens = new ArrayList<>(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - token = token.trim(); - if (token.length() > 0) { - tokens.add(token); - } - } - - List result = new ArrayList<>(tokens.size()); - for (String token: tokens) { - result.add(parseMediaType(token)); - } - return result; - } - - /** - * Parse the given list of (potentially) comma-separated strings into a list of {@code MediaType} objects. - * - *

This method can be used to parse an Accept or Content-Type header. - * - * @param mediaTypes the string to parse. - * - * @return the list of media types. - * - * @throws InvalidMediaTypeException if the media type value cannot be parsed. - */ - public static List parseMediaTypes(List mediaTypes) { - if (mediaTypes == null || mediaTypes.isEmpty()) { - return Collections.emptyList(); - } else if (mediaTypes.size() == 1) { - return parseMediaTypes(mediaTypes.get(0)); - } else { - List result = new ArrayList<>(8); - for (String mediaType: mediaTypes) { - result.addAll(parseMediaTypes(mediaType)); - } - return result; - } - } - - /** - * Sorts the given list of {@code MediaType} objects by specificity. - * - *

Given two media types:

  1. if either media type has a {@linkplain #isWildcardType() wildcard type}, then - * the media type without the wildcard is ordered before the other.
  2. if the two media types have different - * {@linkplain #getType() types}, then they are considered equal and remain their current order.
  3. if either - * media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without the wildcard is - * sorted before the other.
  4. if the two media types have different {@linkplain #getSubtype() subtypes}, then - * they are considered equal and remain their current order.
  5. - *
  6. if the two media types have different {@linkplain #getQualityValue() quality value}, then the media type - * with - * the highest quality value is ordered before the other.
  7. if the two media types have a different amount of - * {@linkplain #getParameter(String) parameters}, then the media type with the most parameters is ordered before the - * other.
  8. - *

For example: - *

audio/basic < audio/* < */*
audio/* < audio/*;q=0.7; - * audio/*;q=0.3
audio/basic;level=1 < audio/basic
audio/basic - * == text/html
audio/basic == audio/wave
- * - * @param mediaTypes the list of media types to be sorted. - * - * @see HTTP 1.1: Semantics and Content, section - * 5.3.2 - */ - public static void sortBySpecificity(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - Collections.sort(mediaTypes, SPECIFICITY_COMPARATOR); - } - } - - /** - * Sorts the given list of {@code MediaType} objects by quality value. - * - *

Given two media types:

  1. if the two media types have different {@linkplain #getQualityValue() quality - * value}, then the media type with the highest quality value is ordered before the other.
  2. if either media - * type has a {@linkplain #isWildcardType() wildcard type}, then the media type without the wildcard is ordered - * before the other.
  3. if the two media types have different {@linkplain #getType() types}, then they are - * considered equal and remain their current order.
  4. - *
  5. if either media type has a {@linkplain #isWildcardSubtype() wildcard subtype}, then the media type without - * the wildcard is sorted before the other.
  6. - *
  7. if the two media types have different {@linkplain #getSubtype() subtypes}, then they are considered equal - * and remain their current order.
  8. if the two media types have a different amount of {@linkplain - * #getParameter(String) parameters}, then the media type with the most parameters is ordered before the - * other.
  9. - *
- * - * @param mediaTypes the list of media types to be sorted. - */ - public static void sortByQualityValue(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - Collections.sort(mediaTypes, QUALITY_VALUE_COMPARATOR); - } - } - - /** - * Sorts the given list of {@code MediaType} objects by specificity as the primary criteria and quality value the - * secondary. - */ - public static void sortBySpecificityAndQuality(List mediaTypes) { - Assert.notNull(mediaTypes, "'mediaTypes' must not be null"); - if (mediaTypes.size() > 1) { - Collections.sort(mediaTypes, new CompoundComparator(MediaType.SPECIFICITY_COMPARATOR, - MediaType.QUALITY_VALUE_COMPARATOR)); - } - } - - /** - * Get the {@link MediaType} of the file. - * - * @param fileName file name. - * - * @return {@link MediaType}, cannot be null. - */ - public static MediaType getFileMediaType(String fileName) { - String extension = getUrlExtension(fileName); - if (!MimeTypeMap.getSingleton().hasExtension(extension)) { - return MediaType.APPLICATION_OCTET_STREAM; - } - - String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - try { - return MediaType.parseMediaType(mimeType); - } catch (Exception e) { - return MediaType.APPLICATION_OCTET_STREAM; - } - } - - /** - * Get he extension by url. - * - * @param url url. - * - * @return extension name. - */ - public static String getUrlExtension(String url) { - String extension = MimeTypeMap.getFileExtensionFromUrl(url); - return extension.isEmpty() ? "" : extension; - } - - /** - * Comparator used by {@link #sortByQualityValue(List)}. - */ - public static final Comparator QUALITY_VALUE_COMPARATOR = new Comparator() { - - @Override - public int compare(MediaType mediaType1, MediaType mediaType2) { - double quality1 = mediaType1.getQualityValue(); - double quality2 = mediaType2.getQualityValue(); - int qualityComparison = Double.compare(quality2, quality1); - if (qualityComparison != 0) { - return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 - } else if (mediaType1.isWildcardType() && !mediaType2.isWildcardType()) { // */* < audio/* - return 1; - } else if (mediaType2.isWildcardType() && !mediaType1.isWildcardType()) { // audio/* > */* - return -1; - } else if (!mediaType1.getType().equals(mediaType2.getType())) { // audio/basic == text/html - return 0; - } else { // mediaType1.getType().equals(mediaType2.getType()) - if (mediaType1.isWildcardSubtype() && !mediaType2.isWildcardSubtype()) { // audio/* < audio/basic - return 1; - } else if (mediaType2.isWildcardSubtype() && !mediaType1.isWildcardSubtype()) { // audio/basic > audio/* - return -1; - } else if (!mediaType1.getSubtype().equals(mediaType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } else { - int paramsSize1 = mediaType1.getParameters().size(); - int paramsSize2 = mediaType2.getParameters().size(); - // audio/basic;level=1 < audio/basic - return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); - } - } - } - }; - - - /** - * Comparator used by {@link #sortBySpecificity(List)}. - */ - public static final Comparator SPECIFICITY_COMPARATOR = new SpecificityComparator() { - - @Override - protected int compareParameters(MediaType mediaType1, MediaType mediaType2) { - double quality1 = mediaType1.getQualityValue(); - double quality2 = mediaType2.getQualityValue(); - int qualityComparison = Double.compare(quality2, quality1); - if (qualityComparison != 0) { - return qualityComparison; // audio/*;q=0.7 < audio/*;q=0.3 - } - return super.compareParameters(mediaType1, mediaType2); - } - }; - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/MimeType.java b/api/src/main/java/com/yanzhenjie/andserver/util/MimeType.java deleted file mode 100644 index a92a328fa5c52bad95e1d00716b32c74a1096bd9..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/MimeType.java +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.yanzhenjie.andserver.error.InvalidMimeTypeException; - -import java.io.Serializable; -import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/6/27. - */ -public class MimeType implements Comparable, Serializable { - - protected static final String WILDCARD_TYPE = "*"; - - private static final String PARAM_CHARSET = "charset"; - - private static final BitSet TOKEN; - - static { - // Variable names refer to RFC 2616, section 2.2. - BitSet ctl = new BitSet(128); - for (int i = 0; i <= 31; i++) { - ctl.set(i); - } - ctl.set(127); - - BitSet separators = new BitSet(128); - separators.set('('); - separators.set(')'); - separators.set('<'); - separators.set('>'); - separators.set('@'); - separators.set(','); - separators.set(';'); - separators.set(':'); - separators.set('\\'); - separators.set('\"'); - separators.set('/'); - separators.set('['); - separators.set(']'); - separators.set('?'); - separators.set('='); - separators.set('{'); - separators.set('}'); - separators.set(' '); - separators.set('\t'); - - TOKEN = new BitSet(128); - TOKEN.set(0, 128); - TOKEN.andNot(ctl); - TOKEN.andNot(separators); - } - - - private final String type; - - private final String subtype; - - private final Map parameters; - - /** - * Create a new {@code Mime} for the given primary type. - * - *

The {@linkplain #getSubtype() subtype} is set to {@code "*"}, and the parameters are empty. - * - * @param type the primary type. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters. - */ - public MimeType(String type) { - this(type, WILDCARD_TYPE); - } - - /** - * Create a new {@code Mime} for the given primary type and subtype. - * - *

The parameters are empty. - * - * @param type the primary type. - * @param subtype the subtype. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters - */ - public MimeType(String type, String subtype) { - this(type, subtype, Collections.emptyMap()); - } - - /** - * Create a new {@code Mime} for the given type, subtype, and character set. - * - * @param type the primary type. - * @param subtype the subtype. - * @param charset the character set. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters. - */ - public MimeType(String type, String subtype, Charset charset) { - this(type, subtype, Collections.singletonMap(PARAM_CHARSET, charset.name())); - } - - /** - * Copy-constructor that copies the type, subtype, parameters of the given {@code Mime}, and allows to set the - * specified character set. - * - * @param other the other media type. - * @param charset the character set. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters. - */ - public MimeType(MimeType other, Charset charset) { - this(other.getType(), other.getSubtype(), addCharsetParameter(charset, other.getParameters())); - } - - /** - * Copy-constructor that copies the type and subtype of the given {@code Mime}, and allows for different parameter. - * - * @param other the other media type. - * @param parameters the parameters, may be null. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters. - */ - public MimeType(MimeType other, Map parameters) { - this(other.getType(), other.getSubtype(), parameters); - } - - /** - * Create a new {@code Mime} for the given type, subtype, and parameters. - * - * @param type the primary type. - * @param subtype the subtype. - * @param parameters the parameters, may be null. - * - * @throws IllegalArgumentException if any of the parameters contains illegal characters. - */ - public MimeType(String type, String subtype, Map parameters) { - checkToken(type); - checkToken(subtype); - this.type = type.toLowerCase(Locale.ENGLISH); - this.subtype = subtype.toLowerCase(Locale.ENGLISH); - if (parameters != null && !parameters.isEmpty()) { - Map map = new LinkedCaseInsensitiveMap<>(parameters.size(), Locale.ENGLISH); - for (Map.Entry entry: parameters.entrySet()) { - String attribute = entry.getKey(); - String value = entry.getValue(); - checkParameters(attribute, value); - map.put(attribute, value); - } - this.parameters = Collections.unmodifiableMap(map); - } else { - this.parameters = Collections.emptyMap(); - } - } - - /** - * Checks the given token string for illegal characters, as defined in RFC 2616, section 2.2. - * - * @throws IllegalArgumentException in case of illegal characters. - * @see HTTP 1.1, section 2.2 - */ - private void checkToken(String token) { - for (int i = 0; i < token.length(); i++) { - char ch = token.charAt(i); - if (!TOKEN.get(ch)) { - throw new IllegalArgumentException("Invalid token character '" + ch + "' in token \"" + token + "\""); - } - } - } - - protected void checkParameters(String attribute, String value) { - Assert.hasLength(attribute, "'attribute' must not be empty."); - Assert.hasLength(value, "'value' must not be empty."); - checkToken(attribute); - if (PARAM_CHARSET.equals(attribute)) { - value = unquote(value); - Charset.forName(value); - } else if (!isQuotedString(value)) { - checkToken(value); - } - } - - private boolean isQuotedString(String s) { - if (s.length() < 2) { - return false; - } else { - return ((s.startsWith("\"") && s.endsWith("\"")) || (s.startsWith("'") && s.endsWith("'"))); - } - } - - protected String unquote(String s) { - if (s == null) { - return null; - } - return isQuotedString(s) ? s.substring(1, s.length() - 1) : s; - } - - /** - * Indicates whether the {@linkplain #getType() type} is the wildcard character * or not. - */ - public boolean isWildcardType() { - return WILDCARD_TYPE.equals(getType()); - } - - /** - * Indicates whether the {@linkplain #getSubtype() subtype} is the wildcard character * or the - * wildcard character followed by a suffix (e.g. *+xml). - * - * @return whether the subtype is a wildcard. - */ - public boolean isWildcardSubtype() { - return WILDCARD_TYPE.equals(getSubtype()) || getSubtype().startsWith("*+"); - } - - /** - * Indicates whether this media type is concrete, i.e. whether neither the type nor the subtype is a wildcard - * character - * *. - * - * @return whether this media type is concrete. - */ - public boolean isConcrete() { - return !isWildcardType() && !isWildcardSubtype(); - } - - /** - * Return the primary type. - */ - public String getType() { - return this.type; - } - - /** - * Return the subtype. - */ - public String getSubtype() { - return this.subtype; - } - - /** - * Return the character set, as indicated by a charset parameter, if any. - * - * @return the character set, or null if not available. - */ - public Charset getCharset() { - String charset = getParameter(PARAM_CHARSET); - return (charset != null ? Charset.forName(unquote(charset)) : null); - } - - /** - * Return a generic parameter value, given a parameter name. - * - * @param name the parameter name. - * - * @return the parameter value, or {@code null} if not present. - */ - public String getParameter(String name) { - return this.parameters.get(name); - } - - /** - * Return all generic parameter values. - * - * @return a read-only map, possibly empty, never null. - */ - public Map getParameters() { - return this.parameters; - } - - /** - * Indicate whether this {@code MediaType} includes the given media type. - * - *

For instance, {@code text/*} includes {@code text/plain} and {@code text/html}, and {@code application/*+xml} - * includes {@code application/soap+xml}, etc. This method is not symmetric. - * - * @param other the reference media type with which to compare. - * - * @return true if this media type includes the given media type, false otherwise. - */ - public boolean includes(MimeType other) { - if (other == null) { - return false; - } - if (this.isWildcardType()) { - // */* includes anything - return true; - } else if (getType().equals(other.getType())) { - if (getSubtype().equals(other.getSubtype())) { - return true; - } - if (this.isWildcardSubtype()) { - // wildcard with suffix, e.g. application/*+xml - int thisPlusIdx = getSubtype().indexOf('+'); - if (thisPlusIdx == -1) { - return true; - } else { - // application/*+xml includes application/soap+xml - int otherPlusIdx = other.getSubtype().indexOf('+'); - if (otherPlusIdx != -1) { - String thisSubtypeNoSuffix = getSubtype().substring(0, thisPlusIdx); - String thisSubtypeSuffix = getSubtype().substring(thisPlusIdx + 1); - String otherSubtypeSuffix = other.getSubtype().substring(otherPlusIdx + 1); - if (thisSubtypeSuffix.equals(otherSubtypeSuffix) && WILDCARD_TYPE.equals(thisSubtypeNoSuffix)) { - return true; - } - } - } - } - } - return false; - } - - /** - * Indicate whether this {@code MediaType} is compatible with the given media type. - * - *

For instance, {@code text/*} is compatible with {@code text/plain}, {@code text/html}, and vice versa. In - * effect, this method is similar to {@link #includes}, except that it is symmetric. - * - * @param other the reference media type with which to compare. - * - * @return true if this media type is compatible with the given media type, false otherwise. - */ - public boolean isCompatibleWith(MimeType other) { - if (other == null) { - return false; - } - if (isWildcardType() || other.isWildcardType()) { - return true; - } else if (getType().equals(other.getType())) { - if (getSubtype().equals(other.getSubtype())) { - return true; - } - // wildcard with suffix? e.g. application/*+xml - if (this.isWildcardSubtype() || other.isWildcardSubtype()) { - - int thisPlusIdx = getSubtype().indexOf('+'); - int otherPlusIdx = other.getSubtype().indexOf('+'); - - if (thisPlusIdx == -1 && otherPlusIdx == -1) { - return true; - } else if (thisPlusIdx != -1 && otherPlusIdx != -1) { - String thisSubtypeNoSuffix = getSubtype().substring(0, thisPlusIdx); - String otherSubtypeNoSuffix = other.getSubtype().substring(0, otherPlusIdx); - - String thisSubtypeSuffix = getSubtype().substring(thisPlusIdx + 1); - String otherSubtypeSuffix = other.getSubtype().substring(otherPlusIdx + 1); - - if (thisSubtypeSuffix.equals(otherSubtypeSuffix) && - (WILDCARD_TYPE.equals(thisSubtypeNoSuffix) || WILDCARD_TYPE.equals(otherSubtypeNoSuffix))) { - return true; - } - } - } - } - return false; - } - - - @Override - public boolean equals(Object other) { - if (!equalsExcludeParameter(other)) { - return false; - } - MimeType otherType = (MimeType) other; - return parametersAreEqual(otherType); - } - - public boolean equalsExcludeParameter(Object other) { - if (this == other) { - return true; - } - if (!(other instanceof MimeType)) { - return false; - } - MimeType otherType = (MimeType) other; - return (this.type.equalsIgnoreCase(otherType.type) && this.subtype.equalsIgnoreCase(otherType.subtype)); - } - - /** - * Determine if the parameters in this {@code Mime} and the supplied {@code Mime} are equal, performing - * case-insensitive comparisons for charsets. - */ - private boolean parametersAreEqual(MimeType other) { - if (this.parameters.size() != other.parameters.size()) { - return false; - } - - for (String key: this.parameters.keySet()) { - if (!other.parameters.containsKey(key)) { - return false; - } - - if (PARAM_CHARSET.equals(key)) { - Charset mCharset = getCharset(); - Charset oCharset = other.getCharset(); - if (mCharset == null || !mCharset.equals(oCharset)) { - return false; - } else { - return true; - } - } - - String mValue = this.parameters.get(key); - String oValue = other.parameters.get(key); - if (mValue == null || !mValue.equals(oValue)) { - return false; - } - } - - return true; - } - - @Override - public int hashCode() { - int result = this.type.hashCode(); - result = 31 * result + this.subtype.hashCode(); - result = 31 * result + this.parameters.hashCode(); - return result; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - appendTo(builder); - return builder.toString(); - } - - protected void appendTo(StringBuilder builder) { - builder.append(this.type); - builder.append('/'); - builder.append(this.subtype); - appendTo(this.parameters, builder); - } - - private void appendTo(Map map, StringBuilder builder) { - for (Map.Entry entry: map.entrySet()) { - builder.append(';'); - builder.append(entry.getKey()); - builder.append('='); - builder.append(entry.getValue()); - } - } - - /** - * Compares this {@code MediaType} to another alphabetically. - * - * @param other media type to compare to. - */ - @Override - public int compareTo(MimeType other) { - int comp = getType().compareToIgnoreCase(other.getType()); - if (comp != 0) { - return comp; - } - comp = getSubtype().compareToIgnoreCase(other.getSubtype()); - if (comp != 0) { - return comp; - } - comp = getParameters().size() - other.getParameters().size(); - if (comp != 0) { - return comp; - } - TreeSet thisAttributes = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - thisAttributes.addAll(getParameters().keySet()); - TreeSet otherAttributes = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); - otherAttributes.addAll(other.getParameters().keySet()); - Iterator thisAttributesIterator = thisAttributes.iterator(); - Iterator otherAttributesIterator = otherAttributes.iterator(); - while (thisAttributesIterator.hasNext()) { - String thisAttribute = thisAttributesIterator.next(); - String otherAttribute = otherAttributesIterator.next(); - comp = thisAttribute.compareToIgnoreCase(otherAttribute); - if (comp != 0) { - return comp; - } - String thisValue = getParameters().get(thisAttribute); - String otherValue = other.getParameters().get(otherAttribute); - if (otherValue == null) { - otherValue = ""; - } - comp = thisValue.compareTo(otherValue); - if (comp != 0) { - return comp; - } - } - return 0; - } - - - /** - * Parse the given string value into a {@code Mime} object. - */ - public static MimeType valueOf(String mimeType) { - if (mimeType.isEmpty()) { - throw new InvalidMimeTypeException(mimeType, "[mimeType] must not be empty"); - } - - int index = mimeType.indexOf(';'); - String fullType = (index >= 0 ? mimeType.substring(0, index) : mimeType).trim(); - if (fullType.isEmpty()) { - throw new InvalidMimeTypeException(mimeType, "'contentType' must not be empty"); - } - - // java.net.HttpURLConnection returns a *; q=.2 Accept header - if (MimeType.WILDCARD_TYPE.equals(fullType)) { - fullType = "*/*"; - } - int subIndex = fullType.indexOf('/'); - if (subIndex == -1) { - throw new InvalidMimeTypeException(mimeType, "does not contain '/'"); - } - if (subIndex == fullType.length() - 1) { - throw new InvalidMimeTypeException(mimeType, "does not contain subtype after '/'"); - } - String type = fullType.substring(0, subIndex); - String subtype = fullType.substring(subIndex + 1, fullType.length()); - if (MimeType.WILDCARD_TYPE.equals(type) && !MimeType.WILDCARD_TYPE.equals(subtype)) { - throw new InvalidMimeTypeException(mimeType, "wildcard type is legal only in '*/*' (all mime " + "types)"); - } - - Map parameters = null; - do { - int nextIndex = index + 1; - boolean quoted = false; - while (nextIndex < mimeType.length()) { - char ch = mimeType.charAt(nextIndex); - if (ch == ';') { - if (!quoted) { - break; - } - } else if (ch == '"') { - quoted = !quoted; - } - nextIndex++; - } - String parameter = mimeType.substring(index + 1, nextIndex).trim(); - if (parameter.length() > 0) { - if (parameters == null) { - parameters = new LinkedHashMap<>(4); - } - int eqIndex = parameter.indexOf('='); - if (eqIndex >= 0) { - String attribute = parameter.substring(0, eqIndex); - String value = parameter.substring(eqIndex + 1, parameter.length()); - parameters.put(attribute, value); - } - } - index = nextIndex; - } - while (index < mimeType.length()); - - try { - return new MimeType(type, subtype, parameters); - } catch (UnsupportedCharsetException ex) { - throw new InvalidMimeTypeException(mimeType, "unsupported charset '" + ex.getCharsetName() + "'"); - } catch (IllegalArgumentException ex) { - throw new InvalidMimeTypeException(mimeType, ex.getMessage()); - } - } - - /** - * Return a string representation of the given list of {@code Mime} objects. - * - * @param mimeTypes the string to parse. - * - * @return the list of mime types. - * - * @throws IllegalArgumentException if the String cannot be parsed. - */ - public static String toString(Collection mimeTypes) { - StringBuilder builder = new StringBuilder(); - for (Iterator iterator = mimeTypes.iterator(); iterator.hasNext(); ) { - MimeType mimeType = iterator.next(); - mimeType.appendTo(builder); - if (iterator.hasNext()) { - builder.append(", "); - } - } - return builder.toString(); - } - - private static Map addCharsetParameter(Charset charset, Map parameters) { - Map map = new LinkedHashMap<>(parameters); - map.put(PARAM_CHARSET, charset.name()); - return map; - } - - public static class SpecificityComparator implements Comparator { - - @Override - public int compare(T mimeType1, T mimeType2) { - if (mimeType1.isWildcardType() && !mimeType2.isWildcardType()) { // */* < audio/* - return 1; - } else if (mimeType2.isWildcardType() && !mimeType1.isWildcardType()) { // audio/* > */* - return -1; - } else if (!mimeType1.getType().equals(mimeType2.getType())) { // audio/basic == text/html - return 0; - } else { - // mediaType1.getType().equals(mediaType2.getType()) - if (mimeType1.isWildcardSubtype() && !mimeType2.isWildcardSubtype()) { // audio/* < audio/basic - return 1; - } else if (mimeType2.isWildcardSubtype() && !mimeType1.isWildcardSubtype()) { // audio/basic > audio/* - return -1; - } else if (!mimeType1.getSubtype().equals(mimeType2.getSubtype())) { // audio/basic == audio/wave - return 0; - } else { // mediaType2.getSubtype().equals(mediaType2.getSubtype()) - return compareParameters(mimeType1, mimeType2); - } - } - } - - @SuppressWarnings("UseCompareMethod") - protected int compareParameters(T mimeType1, T mimeType2) { - int paramsSize1 = mimeType1.getParameters().size(); - int paramsSize2 = mimeType2.getParameters().size(); - // audio/basic;level=1 < audio/basic - return (paramsSize2 < paramsSize1 ? -1 : (paramsSize2 == paramsSize1 ? 0 : 1)); - } - } - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/MimeTypeMap.java b/api/src/main/java/com/yanzhenjie/andserver/util/MimeTypeMap.java deleted file mode 100644 index 5323b4ab20aabc8bfd21523316783ae3b92eeee7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/MimeTypeMap.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.. - * - * 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.util.regex.Pattern; - -public class MimeTypeMap { - - private static final MimeTypeMap sMimeTypeMap = new MimeTypeMap(); - - private MimeTypeMap() { - } - - /** - * Returns the file extension or an empty string if there is no - * extension. This method is a convenience method for obtaining the - * extension of a url and has undefined results for other Strings. - * @param url - * @return The file extension of the given url. - */ - public static String getFileExtensionFromUrl(String url) { - if (!url.isEmpty()) { - int fragment = url.lastIndexOf('#'); - if (fragment > 0) { - url = url.substring(0, fragment); - } - - int query = url.lastIndexOf('?'); - if (query > 0) { - url = url.substring(0, query); - } - - int filenamePos = url.lastIndexOf('/'); - String filename = - 0 <= filenamePos ? url.substring(filenamePos + 1) : url; - - // if the filename contains special characters, we don't - // consider it valid for our matching purposes: - if (!filename.isEmpty() && - Pattern.matches("[a-zA-Z_0-9\\.\\-\\(\\)\\%]+", filename)) { - int dotPos = filename.lastIndexOf('.'); - if (0 <= dotPos) { - return filename.substring(dotPos + 1); - } - } - } - - return ""; - } - - /** - * Return the registered extension for the given MIME type. Note that some - * MIME types map to multiple extensions. This call will return the most - * common extension for the given MIME type. - * @param mimeType A MIME type (i.e. text/plain) - * @return The extension for the given MIME type or {@code null} if there is none. - */ - public String getExtensionFromMimeType(String mimeType) { - return MimeUtils.guessExtensionFromMimeType(mimeType); - } - - - /** - * Return {@code true} if the given extension has a registered MIME type. - * @param extension A file extension without the leading '.' - * @return {@code true} if there is an extension entry in the map. - */ - public boolean hasExtension(String extension) { - return MimeUtils.hasExtension(extension); - } - - /** - * Return the MIME type for the given extension. - * @param extension A file extension without the leading '.' - * @return The MIME type for the given extension or {@code null} if there is none. - */ - public String getMimeTypeFromExtension(String extension) { - return MimeUtils.guessMimeTypeFromExtension(extension); - } - - /** - * Get the singleton instance of MimeTypeMap. - * @return The singleton instance of the MIME-type map. - */ - public static MimeTypeMap getSingleton() { - return sMimeTypeMap; - } -} diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/MimeUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/MimeUtils.java deleted file mode 100644 index 8ac01a77888692bccae8ba1583da34917aff63d3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/MimeUtils.java +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.. - * - * 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.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -public class MimeUtils { - private static final Map mimeTypeToExtensionMap = new HashMap(); - - - private static final Map extensionToMimeTypeMap = new HashMap(); - - - static { - // The following table is based on /etc/mime.types data minus - // chemical/* MIME types and MIME types that don't map to any - // file extensions. We also exclude top-level domain names to - // deal with cases like: - // - // mail.google.com/a/google.com - // - // and "active" MIME types (due to potential security issues). - - - add("application/andrew-inset", "ez"); - add("application/dsptype", "tsp"); - add("application/futuresplash", "spl"); - add("application/hta", "hta"); - add("application/mac-binhex40", "hqx"); - add("application/mac-compactpro", "cpt"); - add("application/mathematica", "nb"); - add("application/msaccess", "mdb"); - add("application/oda", "oda"); - add("application/ogg", "ogg"); - add("application/pdf", "pdf"); - add("application/pgp-keys", "key"); - add("application/pgp-signature", "pgp"); - add("application/pics-rules", "prf"); - add("application/rar", "rar"); - add("application/rdf+xml", "rdf"); - add("application/rss+xml", "rss"); - add("application/zip", "zip"); - add("application/vnd.android.package-archive", "apk"); - add("application/vnd.cinderella", "cdy"); - add("application/vnd.ms-pki.stl", "stl"); - add("application/vnd.oasis.opendocument.database", "odb"); - add("application/vnd.oasis.opendocument.formula", "odf"); - add("application/vnd.oasis.opendocument.graphics", "odg"); - add("application/vnd.oasis.opendocument.graphics-template", "otg"); - add("application/vnd.oasis.opendocument.image", "odi"); - add("application/vnd.oasis.opendocument.spreadsheet", "ods"); - add("application/vnd.oasis.opendocument.spreadsheet-template", "ots"); - add("application/vnd.oasis.opendocument.text", "odt"); - add("application/vnd.oasis.opendocument.text-master", "odm"); - add("application/vnd.oasis.opendocument.text-template", "ott"); - add("application/vnd.oasis.opendocument.text-web", "oth"); - add("application/vnd.google-earth.kml+xml", "kml"); - add("application/vnd.google-earth.kmz", "kmz"); - add("application/msword", "doc"); - add("application/msword", "dot"); - add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx"); - add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx"); - add("application/vnd.ms-excel", "xls"); - add("application/vnd.ms-excel", "xlt"); - add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx"); - add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx"); - add("application/vnd.ms-powerpoint", "ppt"); - add("application/vnd.ms-powerpoint", "pot"); - add("application/vnd.ms-powerpoint", "pps"); - add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx"); - add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx"); - add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx"); - add("application/vnd.rim.cod", "cod"); - add("application/vnd.smaf", "mmf"); - add("application/vnd.stardivision.calc", "sdc"); - add("application/vnd.stardivision.draw", "sda"); - add("application/vnd.stardivision.impress", "sdd"); - add("application/vnd.stardivision.impress", "sdp"); - add("application/vnd.stardivision.math", "smf"); - add("application/vnd.stardivision.writer", "sdw"); - add("application/vnd.stardivision.writer", "vor"); - add("application/vnd.stardivision.writer-global", "sgl"); - add("application/vnd.sun.xml.calc", "sxc"); - add("application/vnd.sun.xml.calc.template", "stc"); - add("application/vnd.sun.xml.draw", "sxd"); - add("application/vnd.sun.xml.draw.template", "std"); - add("application/vnd.sun.xml.impress", "sxi"); - add("application/vnd.sun.xml.impress.template", "sti"); - add("application/vnd.sun.xml.math", "sxm"); - add("application/vnd.sun.xml.writer", "sxw"); - add("application/vnd.sun.xml.writer.global", "sxg"); - add("application/vnd.sun.xml.writer.template", "stw"); - add("application/vnd.visio", "vsd"); - add("application/x-abiword", "abw"); - add("application/x-apple-diskimage", "dmg"); - add("application/x-bcpio", "bcpio"); - add("application/x-bittorrent", "torrent"); - add("application/x-cdf", "cdf"); - add("application/x-cdlink", "vcd"); - add("application/x-chess-pgn", "pgn"); - add("application/x-cpio", "cpio"); - add("application/x-debian-package", "deb"); - add("application/x-debian-package", "udeb"); - add("application/x-director", "dcr"); - add("application/x-director", "dir"); - add("application/x-director", "dxr"); - add("application/x-dms", "dms"); - add("application/x-doom", "wad"); - add("application/x-dvi", "dvi"); - add("application/x-flac", "flac"); - add("application/x-font", "pfa"); - add("application/x-font", "pfb"); - add("application/x-font", "gsf"); - add("application/x-font", "pcf"); - add("application/x-font", "pcf.Z"); - add("application/x-freemind", "mm"); - add("application/x-futuresplash", "spl"); - add("application/x-gnumeric", "gnumeric"); - add("application/x-go-sgf", "sgf"); - add("application/x-graphing-calculator", "gcf"); - add("application/x-gtar", "gtar"); - add("application/x-gtar", "tgz"); - add("application/x-gtar", "taz"); - add("application/x-hdf", "hdf"); - add("application/x-ica", "ica"); - add("application/x-internet-signup", "ins"); - add("application/x-internet-signup", "isp"); - add("application/x-iphone", "iii"); - add("application/x-iso9660-image", "iso"); - add("application/x-jmol", "jmz"); - add("application/x-kchart", "chrt"); - add("application/x-killustrator", "kil"); - add("application/x-koan", "skp"); - add("application/x-koan", "skd"); - add("application/x-koan", "skt"); - add("application/x-koan", "skm"); - add("application/x-kpresenter", "kpr"); - add("application/x-kpresenter", "kpt"); - add("application/x-kspread", "ksp"); - add("application/x-kword", "kwd"); - add("application/x-kword", "kwt"); - add("application/x-latex", "latex"); - add("application/x-lha", "lha"); - add("application/x-lzh", "lzh"); - add("application/x-lzx", "lzx"); - add("application/x-maker", "frm"); - add("application/x-maker", "maker"); - add("application/x-maker", "frame"); - add("application/x-maker", "fb"); - add("application/x-maker", "book"); - add("application/x-maker", "fbdoc"); - add("application/x-mif", "mif"); - add("application/x-ms-wmd", "wmd"); - add("application/x-ms-wmz", "wmz"); - add("application/x-msi", "msi"); - add("application/x-ns-proxy-autoconfig", "pac"); - add("application/x-nwc", "nwc"); - add("application/x-object", "o"); - add("application/x-oz-application", "oza"); - add("application/x-pkcs12", "p12"); - add("application/x-pkcs7-certreqresp", "p7r"); - add("application/x-pkcs7-crl", "crl"); - add("application/x-quicktimeplayer", "qtl"); - add("application/x-shar", "shar"); - add("application/x-shockwave-flash", "swf"); - add("application/x-stuffit", "sit"); - add("application/x-sv4cpio", "sv4cpio"); - add("application/x-sv4crc", "sv4crc"); - add("application/x-tar", "tar"); - add("application/x-texinfo", "texinfo"); - add("application/x-texinfo", "texi"); - add("application/x-troff", "t"); - add("application/x-troff", "roff"); - add("application/x-troff-man", "man"); - add("application/x-ustar", "ustar"); - add("application/x-wais-source", "src"); - add("application/x-wingz", "wz"); - add("application/x-webarchive", "webarchive"); - add("application/x-webarchive-xml", "webarchivexml"); - add("application/x-x509-ca-cert", "crt"); - add("application/x-x509-user-cert", "crt"); - add("application/x-xcf", "xcf"); - add("application/x-xfig", "fig"); - add("application/xhtml+xml", "xhtml"); - add("audio/3gpp", "3gpp"); - add("audio/amr", "amr"); - add("audio/basic", "snd"); - add("audio/midi", "mid"); - add("audio/midi", "midi"); - add("audio/midi", "kar"); - add("audio/midi", "xmf"); - add("audio/mobile-xmf", "mxmf"); - add("audio/mpeg", "mpga"); - add("audio/mpeg", "mpega"); - add("audio/mpeg", "mp2"); - add("audio/mpeg", "mp3"); - add("audio/mpeg", "m4a"); - add("audio/mpegurl", "m3u"); - add("audio/prs.sid", "sid"); - add("audio/x-aiff", "aif"); - add("audio/x-aiff", "aiff"); - add("audio/x-aiff", "aifc"); - add("audio/x-gsm", "gsm"); - add("audio/x-mpegurl", "m3u"); - add("audio/x-ms-wma", "wma"); - add("audio/x-ms-wax", "wax"); - add("audio/x-pn-realaudio", "ra"); - add("audio/x-pn-realaudio", "rm"); - add("audio/x-pn-realaudio", "ram"); - add("audio/x-realaudio", "ra"); - add("audio/x-scpls", "pls"); - add("audio/x-sd2", "sd2"); - add("audio/x-wav", "wav"); - add("image/bmp", "bmp"); - add("audio/x-qcp", "qcp"); - add("image/gif", "gif"); - add("image/ico", "cur"); - add("image/ico", "ico"); - add("image/ief", "ief"); - add("image/jpeg", "jpeg"); - add("image/jpeg", "jpg"); - add("image/jpeg", "jpe"); - add("image/pcx", "pcx"); - add("image/png", "png"); - add("image/svg+xml", "svg"); - add("image/svg+xml", "svgz"); - add("image/tiff", "tiff"); - add("image/tiff", "tif"); - add("image/vnd.djvu", "djvu"); - add("image/vnd.djvu", "djv"); - add("image/vnd.wap.wbmp", "wbmp"); - add("image/x-cmu-raster", "ras"); - add("image/x-coreldraw", "cdr"); - add("image/x-coreldrawpattern", "pat"); - add("image/x-coreldrawtemplate", "cdt"); - add("image/x-corelphotopaint", "cpt"); - add("image/x-icon", "ico"); - add("image/x-jg", "art"); - add("image/x-jng", "jng"); - add("image/x-ms-bmp", "bmp"); - add("image/x-photoshop", "psd"); - add("image/x-portable-anymap", "pnm"); - add("image/x-portable-bitmap", "pbm"); - add("image/x-portable-graymap", "pgm"); - add("image/x-portable-pixmap", "ppm"); - add("image/x-rgb", "rgb"); - add("image/x-xbitmap", "xbm"); - add("image/x-xpixmap", "xpm"); - add("image/x-xwindowdump", "xwd"); - add("model/iges", "igs"); - add("model/iges", "iges"); - add("model/mesh", "msh"); - add("model/mesh", "mesh"); - add("model/mesh", "silo"); - add("text/calendar", "ics"); - add("text/calendar", "icz"); - add("text/comma-separated-values", "csv"); - add("text/css", "css"); - add("text/html", "htm"); - add("text/html", "html"); - add("text/h323", "323"); - add("text/iuls", "uls"); - add("text/mathml", "mml"); - // add ".txt" first so it will be the default for ExtensionFromMimeType - add("text/plain", "txt"); - add("text/plain", "asc"); - add("text/plain", "text"); - add("text/plain", "diff"); - add("text/plain", "po"); // reserve "pot" for vnd.ms-powerpoint - add("text/richtext", "rtx"); - add("text/rtf", "rtf"); - add("text/texmacs", "ts"); - add("text/text", "phps"); - add("text/tab-separated-values", "tsv"); - add("text/xml", "xml"); - add("text/x-bibtex", "bib"); - add("text/x-boo", "boo"); - add("text/x-c++hdr", "h++"); - add("text/x-c++hdr", "hpp"); - add("text/x-c++hdr", "hxx"); - add("text/x-c++hdr", "hh"); - add("text/x-c++src", "c++"); - add("text/x-c++src", "cpp"); - add("text/x-c++src", "cxx"); - add("text/x-chdr", "h"); - add("text/x-component", "htc"); - add("text/x-csh", "csh"); - add("text/x-csrc", "c"); - add("text/x-dsrc", "d"); - add("text/x-haskell", "hs"); - add("text/x-java", "java"); - add("text/x-literate-haskell", "lhs"); - add("text/x-moc", "moc"); - add("text/x-pascal", "p"); - add("text/x-pascal", "pas"); - add("text/x-pcs-gcd", "gcd"); - add("text/x-setext", "etx"); - add("text/x-tcl", "tcl"); - add("text/x-tex", "tex"); - add("text/x-tex", "ltx"); - add("text/x-tex", "sty"); - add("text/x-tex", "cls"); - add("text/x-vcalendar", "vcs"); - add("text/x-vcard", "vcf"); - add("video/3gpp", "3gpp"); - add("video/3gpp", "3gp"); - add("video/3gpp", "3g2"); - add("video/dl", "dl"); - add("video/dv", "dif"); - add("video/dv", "dv"); - add("video/fli", "fli"); - add("video/m4v", "m4v"); - add("video/mpeg", "mpeg"); - add("video/mpeg", "mpg"); - add("video/mpeg", "mpe"); - add("video/mp4", "mp4"); - add("video/mpeg", "VOB"); - add("video/quicktime", "qt"); - add("video/quicktime", "mov"); - add("video/vnd.mpegurl", "mxu"); - add("video/webm", "webm"); - add("video/x-la-asf", "lsf"); - add("video/x-la-asf", "lsx"); - add("video/x-mng", "mng"); - add("video/x-ms-asf", "asf"); - add("video/x-ms-asf", "asx"); - add("video/x-ms-wm", "wm"); - add("video/x-ms-wmv", "wmv"); - add("video/x-ms-wmx", "wmx"); - add("video/x-ms-wvx", "wvx"); - add("video/x-msvideo", "avi"); - add("video/x-sgi-movie", "movie"); - add("x-conference/x-cooltalk", "ice"); - add("x-epoc/x-sisx-app", "sisx"); - applyOverrides(); - } - - - private static void add(String mimeType, String extension) { - // - // if we have an existing x --> y mapping, we do not want to - // override it with another mapping x --> ? - // this is mostly because of the way the mime-type map below - // is constructed (if a mime type maps to several extensions - // the first extension is considered the most popular and is - // added first; we do not want to overwrite it later). - // - if (!mimeTypeToExtensionMap.containsKey(mimeType)) { - mimeTypeToExtensionMap.put(mimeType, extension); - } - extensionToMimeTypeMap.put(extension, mimeType); - } - - - private static InputStream getContentTypesPropertiesStream() { - // User override? - String userTable = System.getProperty("content.types.user.table"); - if (userTable != null) { - File f = new File(userTable); - if (f.exists()) { - try { - return new FileInputStream(f); - } catch (IOException ignored) { - } - } - } - - - // Standard location? - File f = new File(System.getProperty("java.home"), "lib" + File.separator + "content-types.properties"); - if (f.exists()) { - try { - return new FileInputStream(f); - } catch (IOException ignored) { - } - } - - - return null; - } - - - /** - * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your - * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins - * come from "$JAVA_HOME/lib/content-types.properties". - */ - private static void applyOverrides() { - // Get the appropriate InputStream to read overrides from, if any. - InputStream stream = getContentTypesPropertiesStream(); - if (stream == null) { - return; - } - - - try { - try { - // Read the properties file... - Properties overrides = new Properties(); - overrides.load(stream); - // And translate its mapping to ours... - for (Map.Entry entry : overrides.entrySet()) { - String extension = (String) entry.getKey(); - String mimeType = (String) entry.getValue(); - add(mimeType, extension); - } - } finally { - stream.close(); - } - } catch (IOException ignored) { - } - } - - - private MimeUtils() { - } - - - - - - /** - * Returns the MIME type for the given extension. - * @param extension A file extension without the leading '.' - * @return The MIME type for the given extension or null iff there is none. - */ - public static String guessMimeTypeFromExtension(String extension) { - if (extension == null || extension.isEmpty()) { - return null; - } - return extensionToMimeTypeMap.get(extension); - } - - - //下面3个方法根本没有被调用过,因此,我猜测这个类很可能是从其它项目copy过来的。 - //也有可能是因为本项目是经过裁剪的,毕竟是开源社区版 - /** - * Returns true if the given extension has a registered MIME type. - * @param extension A file extension without the leading '.' - * @return True iff there is an extension entry in the map. - */ - public static boolean hasExtension(String extension) { - if (extension == null || extension.isEmpty()) { - return false; - } - return extensionToMimeTypeMap.containsKey(extension); - } - - - /** - * Returns the registered extension for the given MIME type. Note that some - * MIME types map to multiple extensions. This call will return the most - * common extension for the given MIME type. - * @param mimeType A MIME type (i.e. text/plain) - * @return The extension for the given MIME type or null iff there is none. - */ - public static String guessExtensionFromMimeType(String mimeType) { - if (mimeType == null || mimeType.isEmpty()) { - return null; - } - return mimeTypeToExtensionMap.get(mimeType); - } - - /** - * Returns true if the given MIME type has an entry in the map. - * @param mimeType A MIME type (i.e. text/plain) - * @return True iff there is a mimeType entry in the map. - */ - public static boolean hasMimeType(String mimeType) { - if (mimeType == null || mimeType.isEmpty()) { - return false; - } - return mimeTypeToExtensionMap.containsKey(mimeType); - } -} diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/MultiValueMap.java b/api/src/main/java/com/yanzhenjie/andserver/util/MultiValueMap.java deleted file mode 100644 index 3dec8b0feee2e86c144d9e4f10d583e1a61449a4..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/MultiValueMap.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.util.List; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/6/21. - */ -public interface MultiValueMap extends Map> { - - /** - * Return the first value for the given key. - * - * @param key the key. - * - * @return the first value for the specified key, or null. - */ - V getFirst(K key); - - /** - * Add the given single value to the current list of values for the given key. - * - * @param key the key. - * @param value the value to be added. - */ - void add(K key, V value); - - /** - * Set the given single value under the given key. - * - * @param key the key. - * @param value the value to set. - */ - void set(K key, V value); - - /** - * Set the given values under. - * - * @param values the values. - */ - void setAll(Map values); - - /** - * Returns the first values contained in this {@code MultiValueMap}. - * - * @return a single value representation of this map. - */ - Map toSingleValueMap(); - -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/ObjectUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/ObjectUtils.java deleted file mode 100644 index 4fccd5048d8cbc00cd024785c4cdfb1752e5376d..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/ObjectUtils.java +++ /dev/null @@ -1,957 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.lang.reflect.Array; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 2018/7/5. - * - * @deprecated use apache commons-lang instead. - */ -@Deprecated -public abstract class ObjectUtils { - - private static final int INITIAL_HASH = 7; - private static final int MULTIPLIER = 31; - - private static final String EMPTY_STRING = ""; - private static final String NULL_STRING = "null"; - private static final String ARRAY_START = "{"; - private static final String ARRAY_END = "}"; - private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; - private static final String ARRAY_ELEMENT_SEPARATOR = ", "; - - - /** - * Return whether the given throwable is a checked exception: that is, neither a RuntimeException nor an Error. - * - * @param ex the throwable to check. - * - * @return whether the throwable is a checked exception. - */ - public static boolean isCheckedException(Throwable ex) { - return !(ex instanceof RuntimeException || ex instanceof Error); - } - - /** - * Check whether the given exception is compatible with the specified exception types, as declared in a throws - * clause. - * - * @param ex the exception to check. - * @param declaredExceptions the exception types declared in the throws clause. - * - * @return whether the given exception is compatible. - */ - public static boolean isCompatibleWithThrowsClause(Throwable ex, Class... declaredExceptions) { - if (!isCheckedException(ex)) { - return true; - } - if (declaredExceptions != null) { - for (Class declaredException: declaredExceptions) { - if (declaredException.isInstance(ex)) { - return true; - } - } - } - return false; - } - - /** - * Determine whether the given object is an array: either an Object array or a primitive array. - * - * @param obj the object to check. - */ - public static boolean isArray(Object obj) { - return (obj != null && obj.getClass().isArray()); - } - - /** - * Determine whether the given array is empty: i.e. {@code null} or of zero length. - * - * @param array the array to check. - */ - public static boolean isEmpty(Object[] array) { - return (array == null || array.length == 0); - } - - /** - * Determine whether the given object is empty.

This method supports the following object types.

  • {@code - * Array}: considered empty if its length is zero
  • {@link CharSequence}: considered empty if its length is - * zero
  • {@link Collection}: delegates to {@link Collection#isEmpty()}
  • {@link Map}: delegates to - * {@link Map#isEmpty()}

If the given object is non-null and not one of the aforementioned supported - * types, this method returns {@code false}. - * - * @param obj the object to check. - * - * @return {@code true} if the object is {@code null} or empty. - */ - @SuppressWarnings("rawtypes") - public static boolean isEmpty(Object obj) { - if (obj == null) { - return true; - } - - if (obj instanceof CharSequence) { - return ((CharSequence) obj).length() == 0; - } - if (obj.getClass().isArray()) { - return Array.getLength(obj) == 0; - } - if (obj instanceof Collection) { - return ((Collection) obj).isEmpty(); - } - if (obj instanceof Map) { - return ((Map) obj).isEmpty(); - } - return false; - } - - /** - * Check whether the given array contains the given element. - * - * @param array the array to check (may be {@code null}, in which case the return value will always be {@code - * false}). - * @param element the element to check for. - * - * @return whether the element has been found in the given array. - */ - public static boolean containsElement(Object[] array, Object element) { - if (array == null) { - return false; - } - for (Object arrayEle: array) { - if (nullSafeEquals(arrayEle, element)) { - return true; - } - } - return false; - } - - /** - * Check whether the given array of enum constants contains a constant with the given name, ignoring case when - * determining a match. - * - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values(). - * @param constant the constant name to find (must not be null or empty string). - * - * @return whether the constant has been found in the given array. - */ - public static boolean containsConstant(Enum[] enumValues, String constant) { - return containsConstant(enumValues, constant, false); - } - - /** - * Check whether the given array of enum constants contains a constant with the given name. - * - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values(). - * @param constant the constant name to find (must not be null or empty string). - * @param caseSensitive whether case is significant in determining a match. - * - * @return whether the constant has been found in the given array. - */ - public static boolean containsConstant(Enum[] enumValues, String constant, boolean caseSensitive) { - for (Enum candidate: enumValues) { - if (caseSensitive - ? candidate.toString().equals(constant) - : candidate.toString().equalsIgnoreCase(constant)) { - return true; - } - } - return false; - } - - /** - * Case insensitive alternative to {@link Enum#valueOf(Class, String)}. - * - * @param the concrete Enum type. - * @param enumValues the array of all Enum constants in question, usually per Enum.values(). - * @param constant the constant to get the enum value of. - * - * @throws IllegalArgumentException if the given constant is not found in the given array of enum values. Use - * {@link #containsConstant(Enum[], String)} as a guard to avoid this exception. - */ - public static > E caseInsensitiveValueOf(E[] enumValues, String constant) { - for (E candidate: enumValues) { - if (candidate.toString().equalsIgnoreCase(constant)) { - return candidate; - } - } - String message = String.format("constant [%s] does not exist in enum type %s", constant, - enumValues.getClass().getComponentType().getName()); - throw new IllegalArgumentException(message); - } - - /** - * Append the given object to the given array, returning a new array consisting of the input array contents plus the - * given object. - * - * @param array the array to append to (can be {@code null}). - * @param obj the object to append. - * - * @return the new array (of the same component type; never {@code null}). - */ - public static A[] addObjectToArray(A[] array, O obj) { - Class compType = Object.class; - if (array != null) { - compType = array.getClass().getComponentType(); - } else if (obj != null) { - compType = obj.getClass(); - } - int newArrLength = (array != null ? array.length + 1 : 1); - @SuppressWarnings("unchecked") A[] newArr = (A[]) Array.newInstance(compType, newArrLength); - if (array != null) { - System.arraycopy(array, 0, newArr, 0, array.length); - } - newArr[newArr.length - 1] = obj; - return newArr; - } - - /** - * Convert the given array (which may be a primitive array) to an object array (if necessary of primitive wrapper - * objects).

A {@code null} source value will be converted to an empty Object array. - * - * @param source the (potentially primitive) array. - * - * @return the corresponding object array (never {@code null}). - * - * @throws IllegalArgumentException if the parameter is not an array. - */ - public static Object[] toObjectArray(Object source) { - if (source instanceof Object[]) { - return (Object[]) source; - } - if (source == null) { - return new Object[0]; - } - if (!source.getClass().isArray()) { - throw new IllegalArgumentException("Source is not an array: " + source); - } - int length = Array.getLength(source); - if (length == 0) { - return new Object[0]; - } - Class wrapperType = Array.get(source, 0).getClass(); - Object[] newArray = (Object[]) Array.newInstance(wrapperType, length); - for (int i = 0; i < length; i++) { - newArray[i] = Array.get(source, i); - } - return newArray; - } - - - //--------------------------------------------------------------------- - // Convenience methods for content-based equality/hash-code handling - //--------------------------------------------------------------------- - - /** - * Determine if the given objects are equal, returning {@code true} if both are {@code null} or {@code false} if - * only one is {@code null}.

Compares arrays with {@code Arrays.equals}, performing an equality check based on - * the array elements rather than the array reference. - * - * @param o1 first Object to compare. - * @param o2 second Object to compare. - * - * @return whether the given objects are equal. - * - * @see Object#equals(Object) - * @see Arrays#equals - */ - public static boolean nullSafeEquals(Object o1, Object o2) { - if (o1 == o2) { - return true; - } - if (o1 == null || o2 == null) { - return false; - } - if (o1.equals(o2)) { - return true; - } - if (o1.getClass().isArray() && o2.getClass().isArray()) { - return arrayEquals(o1, o2); - } - return false; - } - - /** - * Compare the given arrays with {@code Arrays.equals}, performing an equality check based on the array elements - * rather than the array reference. - * - * @param o1 first array to compare. - * @param o2 second array to compare. - * - * @return whether the given objects are equal. - * - * @see #nullSafeEquals(Object, Object) - * @see Arrays#equals - */ - private static boolean arrayEquals(Object o1, Object o2) { - if (o1 instanceof Object[] && o2 instanceof Object[]) { - return Arrays.equals((Object[]) o1, (Object[]) o2); - } - if (o1 instanceof boolean[] && o2 instanceof boolean[]) { - return Arrays.equals((boolean[]) o1, (boolean[]) o2); - } - if (o1 instanceof byte[] && o2 instanceof byte[]) { - return Arrays.equals((byte[]) o1, (byte[]) o2); - } - if (o1 instanceof char[] && o2 instanceof char[]) { - return Arrays.equals((char[]) o1, (char[]) o2); - } - if (o1 instanceof double[] && o2 instanceof double[]) { - return Arrays.equals((double[]) o1, (double[]) o2); - } - if (o1 instanceof float[] && o2 instanceof float[]) { - return Arrays.equals((float[]) o1, (float[]) o2); - } - if (o1 instanceof int[] && o2 instanceof int[]) { - return Arrays.equals((int[]) o1, (int[]) o2); - } - if (o1 instanceof long[] && o2 instanceof long[]) { - return Arrays.equals((long[]) o1, (long[]) o2); - } - if (o1 instanceof short[] && o2 instanceof short[]) { - return Arrays.equals((short[]) o1, (short[]) o2); - } - return false; - } - - /** - * Return as hash code for the given object; typically the value of {@code Object#hashCode()}}. If the object is an - * array, this method will delegate to any of the {@code nullSafeHashCode} methods for arrays in this class. If the - * object is {@code null}, this method returns 0. - * - * @see Object#hashCode() - * @see #nullSafeHashCode(Object[]) - * @see #nullSafeHashCode(boolean[]) - * @see #nullSafeHashCode(byte[]) - * @see #nullSafeHashCode(char[]) - * @see #nullSafeHashCode(double[]) - * @see #nullSafeHashCode(float[]) - * @see #nullSafeHashCode(int[]) - * @see #nullSafeHashCode(long[]) - * @see #nullSafeHashCode(short[]) - */ - public static int nullSafeHashCode(Object obj) { - if (obj == null) { - return 0; - } - if (obj.getClass().isArray()) { - if (obj instanceof Object[]) { - return nullSafeHashCode((Object[]) obj); - } - if (obj instanceof boolean[]) { - return nullSafeHashCode((boolean[]) obj); - } - if (obj instanceof byte[]) { - return nullSafeHashCode((byte[]) obj); - } - if (obj instanceof char[]) { - return nullSafeHashCode((char[]) obj); - } - if (obj instanceof double[]) { - return nullSafeHashCode((double[]) obj); - } - if (obj instanceof float[]) { - return nullSafeHashCode((float[]) obj); - } - if (obj instanceof int[]) { - return nullSafeHashCode((int[]) obj); - } - if (obj instanceof long[]) { - return nullSafeHashCode((long[]) obj); - } - if (obj instanceof short[]) { - return nullSafeHashCode((short[]) obj); - } - } - return obj.hashCode(); - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(Object[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (Object element: array) { - hash = MULTIPLIER * hash + nullSafeHashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(boolean[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (boolean element: array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(byte[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (byte element: array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(char[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (char element: array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(double[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (double element: array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(float[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (float element: array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(int[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (int element: array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(long[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (long element: array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. If {@code array} is {@code null}, this method - * returns 0. - */ - public static int nullSafeHashCode(short[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (short element: array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return the same value as {@link Boolean#hashCode()}}. - * - * @see Boolean#hashCode() - */ - public static int hashCode(boolean bool) { - return (bool ? 1231 : 1237); - } - - /** - * Return the same value as {@link Double#hashCode()}}. - * - * @see Double#hashCode() - */ - public static int hashCode(double dbl) { - return hashCode(Double.doubleToLongBits(dbl)); - } - - /** - * Return the same value as {@link Float#hashCode()}}. - * - * @see Float#hashCode() - */ - public static int hashCode(float flt) { - return Float.floatToIntBits(flt); - } - - /** - * Return the same value as {@link Long#hashCode()}}. - * - * @see Long#hashCode() - */ - public static int hashCode(long lng) { - return (int) (lng ^ (lng >>> 32)); - } - - - //--------------------------------------------------------------------- - // Convenience methods for toString output - //--------------------------------------------------------------------- - - /** - * Return a String representation of an object's overall identity. - * - * @param obj the object (may be {@code null}). - * - * @return the object's identity as String representation, or an empty String if the object was {@code null}. - */ - public static String identityToString(Object obj) { - if (obj == null) { - return EMPTY_STRING; - } - return obj.getClass().getName() + "@" + getIdentityHexString(obj); - } - - /** - * Return a hex String form of an object's identity hash code. - * - * @param obj the object. - * - * @return the object's identity code in hex notation. - */ - public static String getIdentityHexString(Object obj) { - return Integer.toHexString(System.identityHashCode(obj)); - } - - /** - * Return a content-based String representation if {@code obj} is not {@code null}; otherwise returns an empty - * String. - *

Differs from {@link #nullSafeToString(Object)} in that it returns an empty String rather than "null" for a - * {@code null} value. - * - * @param obj the object to build a display String for. - * - * @return a display String representation of {@code obj}. - * - * @see #nullSafeToString(Object) - */ - public static String getDisplayString(Object obj) { - if (obj == null) { - return EMPTY_STRING; - } - return nullSafeToString(obj); - } - - /** - * Determine the class name for the given object.

Returns {@code "null"} if {@code obj} is {@code null}. - * - * @param obj the object to introspect (may be {@code null}). - * - * @return the corresponding class name. - */ - public static String nullSafeClassName(Object obj) { - return (obj != null ? obj.getClass().getName() : NULL_STRING); - } - - /** - * Return a String representation of the specified Object. - * - *

Builds a String representation of the contents in case of an array. Returns {@code "null"} if {@code obj} is - * {@code null}. - * - * @param obj the object to build a String representation for. - * - * @return a String representation of {@code obj}. - */ - public static String nullSafeToString(Object obj) { - if (obj == null) { - return NULL_STRING; - } - if (obj instanceof String) { - return (String) obj; - } - if (obj instanceof Object[]) { - return nullSafeToString((Object[]) obj); - } - if (obj instanceof boolean[]) { - return nullSafeToString((boolean[]) obj); - } - if (obj instanceof byte[]) { - return nullSafeToString((byte[]) obj); - } - if (obj instanceof char[]) { - return nullSafeToString((char[]) obj); - } - if (obj instanceof double[]) { - return nullSafeToString((double[]) obj); - } - if (obj instanceof float[]) { - return nullSafeToString((float[]) obj); - } - if (obj instanceof int[]) { - return nullSafeToString((int[]) obj); - } - if (obj instanceof long[]) { - return nullSafeToString((long[]) obj); - } - if (obj instanceof short[]) { - return nullSafeToString((short[]) obj); - } - String str = obj.toString(); - return (str != null ? str : EMPTY_STRING); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(Object[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(String.valueOf(array[i])); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(boolean[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(byte[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(char[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append("'").append(array[i]).append("'"); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(double[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(float[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(int[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(long[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - * - *

The String representation consists of a list of the array's elements, enclosed in curly braces ({@code - * "{}"}). Adjacent elements are separated by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * - * @param array the array to build a String representation for. - * - * @return a String representation of {@code array}. - */ - public static String nullSafeToString(short[] array) { - if (array == null) { - return NULL_STRING; - } - - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/Patterns.java b/api/src/main/java/com/yanzhenjie/andserver/util/Patterns.java deleted file mode 100644 index 4051c8b6eee8b0452d3581bc9fd4d72d28d86def..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/Patterns.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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; - -/** - * Created by Zhenjie Yan on 2018/9/5. - */ -public interface Patterns { - - String WORD = "[a-zA-Z0-9_\\-\\.]%s"; - - String PATH_0 = String.format(WORD, "*"); - String PATH_1 = String.format(WORD, "+"); - String PATH = String.format("((/%s)|((/%s)+))|((/%s)+/)", PATH_0, PATH_1, PATH_1); - - String PAIR_KEY = String.format(WORD, "+"); - String PAIR_VALUE = "(.)*"; - String PAIR_KEY_VALUE = String.format("(%s)(=)(%s)", PAIR_KEY, PAIR_VALUE); - String PAIR_NO_KEY = String.format("!%s", PAIR_KEY); - String PAIR_NO_VALUE = String.format("(%s)(!=)(%s)", PAIR_KEY, PATH_1); - - String FORWARD = "forward:(.)*"; - String REDIRECT = "redirect:(.)*"; -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/StatusCode.java b/api/src/main/java/com/yanzhenjie/andserver/util/StatusCode.java deleted file mode 100644 index 0aa89ee4294ac90f6ff0fe980eae310503c25b9f..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/StatusCode.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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; - -/** - * Created by Zhenjie Yan on 2018/7/26. - * - * @deprecated use {@link com.yanzhenjie.andserver.http.StatusCode} instead. - */ -@Deprecated -public interface StatusCode extends com.yanzhenjie.andserver.http.StatusCode { -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/StringUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/StringUtils.java deleted file mode 100644 index a7df420b16cd660097327635ccf4aef3be65785c..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/StringUtils.java +++ /dev/null @@ -1,1232 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.util.*; - -/** - * Created by Zhenjie Yan on 2018/7/10. - * - * @deprecated use apache commons-lang instead. - */ -@Deprecated -public abstract class StringUtils { - - private static final String FOLDER_SEPARATOR = "/"; - private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; - private static final String TOP_PATH = ".."; - private static final String CURRENT_PATH = "."; - private static final char EXTENSION_SEPARATOR = '.'; - - //------------------------------------------------------- - // General convenience methods for working with Strings - //------------------------------------------------------- - - /** - * Check whether the given {@code String} is empty. - * - *

This method accepts any Object as an argument, comparing it to null and the empty String. As a consequence, - * this method will never return true for a non-null non-String object. - * - *

The Object signature is useful for general attribute handling code that commonly deals with Strings but - * generally has to iterate over Objects since attributes may e.g. be primitive value objects as well. - * - * @param str the candidate string. - */ - public static boolean isEmpty(Object str) { - return (str == null || "".equals(str)); - } - - /** - * Check that the given {@code CharSequence} is neither null nor of length 0. - * - *

Note: this method returns true for a {@code CharSequence} that purely consists of whitespace. - * - *

 StringUtils.hasLength(null) = false StringUtils.hasLength("") = false
-     * StringUtils.hasLength(" ") = true StringUtils.hasLength("Hello") = true 
- * - * @param str the {@code CharSequence} to check (may be null). - * - * @return true if the {@code CharSequence} is not null and has length. - */ - public static boolean hasLength(CharSequence str) { - return (str != null && str.length() > 0); - } - - /** - * Check that the given {@code String} is neither null nor of length 0. - * - *

Note: this method returns true for a {@code String} that purely consists of whitespace. - * - * @param str the {@code String} to check (may be null). - * - * @return true if the {@code String} is not null and has length. - */ - public static boolean hasLength(String str) { - return (str != null && !str.isEmpty()); - } - - /** - * Check whether the given {@code CharSequence} contains actual text. - * - *

More specifically, this method returns true if the {@code CharSequence} is not null, its length is greater - * than 0, and it contains at least one non-whitespace character. - * - *

 StringUtils.hasText(null) = false StringUtils.hasText("") = false StringUtils.hasText(" ")
-     * = false StringUtils.hasText("12345") = true StringUtils.hasText(" 12345 ") = true 
- * - * @param str the {@code CharSequence} to check (may be null). - * - * @return true if the {@code CharSequence} is not null, its length is greater than 0, and it does not contain - * whitespace only. - */ - public static boolean hasText(CharSequence str) { - return (hasLength(str) && containsText(str)); - } - - /** - * Check whether the given {@code String} contains actual text. - * - *

More specifically, this method returns true if the {@code String} is not null, its length is greater than 0, - * and it contains at least one non-whitespace character. - * - * @param str the {@code String} to check (may be null). - * - * @return true if the {@code String} is not null, its length is greater than 0, and it does not contain whitespace - * only. - */ - public static boolean hasText(String str) { - return (hasLength(str) && containsText(str)); - } - - private static boolean containsText(CharSequence str) { - int strLen = str.length(); - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return true; - } - } - return false; - } - - /** - * Check whether the given {@code CharSequence} contains any whitespace characters. - * - * @param str the {@code CharSequence} to check (may be null). - * - * @return true if the {@code CharSequence} is not empty and contains at least 1 whitespace character. - */ - public static boolean containsWhitespace(CharSequence str) { - if (!hasLength(str)) { - return false; - } - - int strLen = str.length(); - for (int i = 0; i < strLen; i++) { - if (Character.isWhitespace(str.charAt(i))) { - return true; - } - } - return false; - } - - /** - * Check whether the given {@code String} contains any whitespace characters. - * - * @param str the {@code String} to check (may be null). - * - * @return true if the {@code String} is not empty and contains at least 1 whitespace character. - */ - public static boolean containsWhitespace(String str) { - return containsWhitespace((CharSequence) str); - } - - /** - * Trim leading and trailing whitespace from the given {@code String}. - * - * @param str the {@code String} to check. - * - * @return the trimmed {@code String}. - */ - public static String trimWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { - sb.deleteCharAt(0); - } - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - /** - * Trim all whitespace from the given {@code String}: leading, trailing, and in between characters. - * - * @param str the {@code String} to check. - * - * @return the trimmed {@code String}. - */ - public static String trimAllWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - int len = str.length(); - StringBuilder sb = new StringBuilder(str.length()); - for (int i = 0; i < len; i++) { - char c = str.charAt(i); - if (!Character.isWhitespace(c)) { - sb.append(c); - } - } - return sb.toString(); - } - - /** - * Trim leading whitespace from the given {@code String}. - * - * @param str the {@code String} to check. - * - * @return the trimmed {@code String}. - */ - public static String trimLeadingWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { - sb.deleteCharAt(0); - } - return sb.toString(); - } - - /** - * Trim trailing whitespace from the given {@code String}. - * - * @param str the {@code String} to check. - * - * @return the trimmed {@code String}. - */ - public static String trimTrailingWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - /** - * Trim all occurrences of the supplied leading character from the given {@code String}. - * - * @param str the {@code String} to check. - * @param leadingCharacter the leading character to be trimmed. - * - * @return the trimmed {@code String}. - */ - public static String trimLeadingCharacter(String str, char leadingCharacter) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) { - sb.deleteCharAt(0); - } - return sb.toString(); - } - - /** - * Trim all occurrences of the supplied trailing character from the given {@code String}. - * - * @param str the {@code String} to check. - * @param trailingCharacter the trailing character to be trimmed. - * - * @return the trimmed {@code String}. - */ - public static String trimTrailingCharacter(String str, char trailingCharacter) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - /** - * Test if the given {@code String} starts with the specified prefix, ignoring upper/lower case. - * - * @param str the {@code String} to check. - * @param prefix the prefix to look for. - */ - public static boolean startsWithIgnoreCase(String str, String prefix) { - return (str != null && prefix != null && str.length() >= prefix.length() && - str.regionMatches(true, 0, prefix, 0, prefix.length())); - } - - /** - * Test if the given {@code String} ends with the specified suffix, ignoring upper/lower case. - * - * @param str the {@code String} to check. - * @param suffix the suffix to look for. - */ - public static boolean endsWithIgnoreCase(String str, String suffix) { - return (str != null && suffix != null && str.length() >= suffix.length() && - str.regionMatches(true, str.length() - suffix.length(), suffix, 0, suffix.length())); - } - - /** - * Test whether the given string matches the given substring at the given index. - * - * @param str the original string (or StringBuilder). - * @param index the index in the original string to start matching against. - * @param substring the substring to match at the given index. - */ - public static boolean substringMatch(CharSequence str, int index, CharSequence substring) { - if (index + substring.length() > str.length()) { - return false; - } - for (int i = 0; i < substring.length(); i++) { - if (str.charAt(index + i) != substring.charAt(i)) { - return false; - } - } - return true; - } - - /** - * Count the occurrences of the substring {@code sub} in string {@code str}. - * - * @param str string to search in. - * @param sub string to search for. - */ - public static int countOccurrencesOf(String str, String sub) { - if (!hasLength(str) || !hasLength(sub)) { - return 0; - } - - int count = 0; - int pos = 0; - int idx; - while ((idx = str.indexOf(sub, pos)) != -1) { - ++count; - pos = idx + sub.length(); - } - return count; - } - - /** - * Replace all occurrences of a substring within a string with another string. - * - * @param inString {@code String} to examine. - * @param oldPattern {@code String} to replace. - * @param newPattern {@code String} to insert. - * - * @return a {@code String} with the replacements. - */ - public static String replace(String inString, String oldPattern, String newPattern) { - if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) { - return inString; - } - int index = inString.indexOf(oldPattern); - if (index == -1) { - // no occurrence -> can return input as-is - return inString; - } - - int capacity = inString.length(); - if (newPattern.length() > oldPattern.length()) { - capacity += 16; - } - StringBuilder sb = new StringBuilder(capacity); - - int pos = 0; // our position in the old string - int patLen = oldPattern.length(); - while (index >= 0) { - sb.append(inString.substring(pos, index)); - sb.append(newPattern); - pos = index + patLen; - index = inString.indexOf(oldPattern, pos); - } - - // append any characters to the right of a match - sb.append(inString.substring(pos)); - return sb.toString(); - } - - /** - * Delete all occurrences of the given substring. - * - * @param inString the original {@code String}. - * @param pattern the pattern to delete all occurrences of. - * - * @return the resulting {@code String}. - */ - public static String delete(String inString, String pattern) { - return replace(inString, pattern, ""); - } - - /** - * Delete any character in a given {@code String}. - * - * @param inString the original {@code String}. - * @param charsToDelete a set of characters to delete. E.g. "az\n" will delete 'a's, 'z's and new lines. - * - * @return the resulting {@code String}. - */ - public static String deleteAny(String inString, String charsToDelete) { - if (!hasLength(inString) || !hasLength(charsToDelete)) { - return inString; - } - - StringBuilder sb = new StringBuilder(inString.length()); - for (int i = 0; i < inString.length(); i++) { - char c = inString.charAt(i); - if (charsToDelete.indexOf(c) == -1) { - sb.append(c); - } - } - return sb.toString(); - } - - - //--------------------------------------------------------- - // Convenience methods for working with formatted Strings - //--------------------------------------------------------- - - /** - * Quote the given {@code String} with single quotes. - * - * @param str the input {@code String} (e.g. "myString"). - * - * @return the quoted {@code String} (e.g. "'myString'"), or null if the input was null. - */ - public static String quote(String str) { - return (str != null ? "'" + str + "'" : null); - } - - /** - * Turn the given Object into a {@code String} with single quotes if it is a {@code String}; keeping the Object - * as-is else. - * - * @param obj the input Object (e.g. "myString"). - * - * @return the quoted {@code String} (e.g. "'myString'"), or the input object as-is if not a {@code String}. - */ - public static Object quoteIfString(Object obj) { - return (obj instanceof String ? quote((String) obj) : obj); - } - - /** - * Unqualify a string qualified by a '.' dot character. For example, "this.name.is.qualified", returns "qualified". - * - * @param qualifiedName the qualified name. - */ - public static String unqualify(String qualifiedName) { - return unqualify(qualifiedName, '.'); - } - - /** - * Unqualify a string qualified by a separator character. For example, "this:name:is:qualified" returns "qualified" - * if using a ':' separator. - * - * @param qualifiedName the qualified name. - * @param separator the separator. - */ - public static String unqualify(String qualifiedName, char separator) { - return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1); - } - - /** - * Capitalize a {@code String}, changing the first letter to upper case as per {@link Character#toUpperCase(char)}. - * No other letters are changed. - * - * @param str the {@code String} to capitalize. - * - * @return the capitalized {@code String}. - */ - public static String capitalize(String str) { - return changeFirstCharacterCase(str, true); - } - - /** - * Uncapitalize a {@code String}, changing the first letter to lower case as per {@link - * Character#toLowerCase(char)}. No other letters are changed. - * - * @param str the {@code String} to uncapitalize. - * - * @return the uncapitalized {@code String}. - */ - public static String uncapitalize(String str) { - return changeFirstCharacterCase(str, false); - } - - private static String changeFirstCharacterCase(String str, boolean capitalize) { - if (!hasLength(str)) { - return str; - } - - char baseChar = str.charAt(0); - char updatedChar; - if (capitalize) { - updatedChar = Character.toUpperCase(baseChar); - } else { - updatedChar = Character.toLowerCase(baseChar); - } - if (baseChar == updatedChar) { - return str; - } - - char[] chars = str.toCharArray(); - chars[0] = updatedChar; - return new String(chars, 0, chars.length); - } - - /** - * Extract the filename from the given Java resource path, e.g. {@code "mypath/myfile.txt" -> "myfile.txt"}. - * - * @param path the file path (may be null). - * - * @return the extracted filename, or null if none. - */ - public static String getFilename(String path) { - if (path == null) { - return null; - } - - int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); - return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path); - } - - /** - * Extract the filename extension from the given Java resource path, e.g. "mypath/myfile.txt" -> "txt". - * - * @param path the file path (may be null). - * - * @return the extracted filename extension, or null if none. - */ - public static String getFilenameExtension(String path) { - if (path == null) { - return null; - } - - int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR); - if (extIndex == -1) { - return null; - } - - int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (folderIndex > extIndex) { - return null; - } - - return path.substring(extIndex + 1); - } - - /** - * Strip the filename extension from the given Java resource path, e.g. "mypath/myfile.txt" -> "mypath/myfile". - * - * @param path the file path. - * - * @return the path with stripped filename extension. - */ - public static String stripFilenameExtension(String path) { - if (path == null) { - return null; - } - - int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR); - if (extIndex == -1) { - return path; - } - - int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (folderIndex > extIndex) { - return path; - } - - return path.substring(0, extIndex); - } - - /** - * Apply the given relative path to the given Java resource path, assuming standard Java folder separation (i.e. "/" - * separators). - * - * @param path the path to start from (usually a full file path). - * @param relativePath the relative path to apply (relative to the full file path above). - * - * @return the full file path that results from applying the relative path. - */ - public static String applyRelativePath(String path, String relativePath) { - int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (separatorIndex != -1) { - String newPath = path.substring(0, separatorIndex); - if (!relativePath.startsWith(FOLDER_SEPARATOR)) { - newPath += FOLDER_SEPARATOR; - } - return newPath + relativePath; - } else { - return relativePath; - } - } - - /** - * Normalize the path by suppressing sequences like "path/.." and inner simple dots.

The result is convenient for - * path comparison. For other uses, notice that Windows separators ("\") are replaced by simple slashes. - * - * @param path the original path. - * - * @return the normalized path. - */ - public static String cleanPath(String path) { - if (path == null) { - return null; - } - String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); - - // Strip prefix from path to analyze, to not treat it as part of the - // first path element. This is necessary to correctly parse paths like - // "file:core/../core/io/Resource.class", where the ".." should just - // strip the first "core" directory while keeping the "file:" prefix. - int prefixIndex = pathToUse.indexOf(":"); - String prefix = ""; - if (prefixIndex != -1) { - prefix = pathToUse.substring(0, prefixIndex + 1); - if (prefix.contains("/")) { - prefix = ""; - } else { - pathToUse = pathToUse.substring(prefixIndex + 1); - } - } - if (pathToUse.startsWith(FOLDER_SEPARATOR)) { - prefix = prefix + FOLDER_SEPARATOR; - pathToUse = pathToUse.substring(1); - } - - String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR); - List pathElements = new LinkedList(); - int tops = 0; - - for (int i = pathArray.length - 1; i >= 0; i--) { - String element = pathArray[i]; - if (CURRENT_PATH.equals(element)) { - // Points to current directory - drop it. - } else if (TOP_PATH.equals(element)) { - // Registering top path found. - tops++; - } else { - if (tops > 0) { - // Merging path element with element corresponding to top path. - tops--; - } else { - // Normal path element found. - pathElements.add(0, element); - } - } - } - - // Remaining top paths need to be retained. - for (int i = 0; i < tops; i++) { - pathElements.add(0, TOP_PATH); - } - - return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); - } - - /** - * Compare two paths after normalization of them. - * - * @param path1 first path for comparison. - * @param path2 second path for comparison. - * - * @return whether the two paths are equivalent after normalization. - */ - public static boolean pathEquals(String path1, String path2) { - return cleanPath(path1).equals(cleanPath(path2)); - } - - /** - * Parse the given {@code localeString} value into a {@link Locale}.

This is the inverse operation of {@link - * Locale#toString Locale's toString}. - * - * @param localeString the locale {@code String}, following {@code Locale's} {@code toString()} format ("en", - * "en_UK", etc); also accepts spaces as separators, as an alternative to underscores. - * - * @return a corresponding {@code Locale} instance, or {@code null} if none. - * - * @throws IllegalArgumentException in case of an invalid locale specification. - */ - public static Locale parseLocaleString(String localeString) { - String[] parts = tokenizeToStringArray(localeString, "_ ", false, false); - String language = (parts.length > 0 ? parts[0] : ""); - String country = (parts.length > 1 ? parts[1] : ""); - - validateLocalePart(language); - validateLocalePart(country); - - String variant = ""; - if (parts.length > 2) { - // There is definitely a variant, and it is everything after the country - // code sans the separator between the country code and the variant. - int endIndexOfCountryCode = localeString.indexOf(country, language.length()) + country.length(); - // Strip off any leading '_' and whitespace, what's left is the variant. - variant = trimLeadingWhitespace(localeString.substring(endIndexOfCountryCode)); - if (variant.startsWith("_")) { - variant = trimLeadingCharacter(variant, '_'); - } - } - return (language.length() > 0 ? new Locale(language, country, variant) : null); - } - - private static void validateLocalePart(String localePart) { - for (int i = 0; i < localePart.length(); i++) { - char ch = localePart.charAt(i); - if (ch != ' ' && ch != '_' && ch != '#' && !Character.isLetterOrDigit(ch)) { - String message = "Locale part \"" + localePart + "\" contains invalid characters"; - throw new IllegalArgumentException(message); - } - } - } - - /** - * Determine the RFC 3066 compliant language tag, as used for the HTTP "Accept-Language" header. - * - * @param locale the Locale to transform to a language tag. - * - * @return the RFC 3066 compliant language tag as {@code String}. - */ - public static String toLanguageTag(Locale locale) { - return locale.getLanguage() + (hasText(locale.getCountry()) ? "-" + locale.getCountry() : ""); - } - - /** - * Parse the given {@code timeZoneString} value into a {@link TimeZone}. - * - * @param timeZoneString the time zone {@code String}, following {@link TimeZone#getTimeZone(String)} but - * throwing {@link IllegalArgumentException} in case of an invalid time zone specification. - * - * @return a corresponding {@link TimeZone} instance. - * - * @throws IllegalArgumentException in case of an invalid time zone specification. - */ - public static TimeZone parseTimeZoneString(String timeZoneString) { - TimeZone timeZone = TimeZone.getTimeZone(timeZoneString); - if ("GMT".equals(timeZone.getID()) && !timeZoneString.startsWith("GMT")) { - // We don't want that GMT fallback... - throw new IllegalArgumentException("Invalid time zone specification '" + timeZoneString + "'"); - } - return timeZone; - } - - - //----------------------------------------------------- - // Convenience methods for working with String arrays - //----------------------------------------------------- - - /** - * Append the given {@code String} to the given {@code String} array, returning a new array consisting of the input - * array contents plus the given {@code String}. - * - * @param array the array to append to (can be {@code null}). - * @param str the {@code String} to append. - * - * @return the new array (never {@code null}). - */ - public static String[] addStringToArray(String[] array, String str) { - if (ObjectUtils.isEmpty(array)) { - return new String[] {str}; - } - - String[] newArr = new String[array.length + 1]; - System.arraycopy(array, 0, newArr, 0, array.length); - newArr[array.length] = str; - return newArr; - } - - /** - * Concatenate the given {@code String} arrays into one, with overlapping array elements included twice.

The - * order of elements in the original arrays is preserved. - * - * @param array1 the first array (can be {@code null}). - * @param array2 the second array (can be {@code null}). - * - * @return the new array ({@code null} if both given arrays were {@code null}). - */ - public static String[] concatenateStringArrays(String[] array1, String[] array2) { - if (ObjectUtils.isEmpty(array1)) { - return array2; - } - if (ObjectUtils.isEmpty(array2)) { - return array1; - } - - String[] newArr = new String[array1.length + array2.length]; - System.arraycopy(array1, 0, newArr, 0, array1.length); - System.arraycopy(array2, 0, newArr, array1.length, array2.length); - return newArr; - } - - /** - * Merge the given {@code String} arrays into one, with overlapping array elements only included once.

The order - * of elements in the original arrays is preserved (with the exception of overlapping elements, which are only - * included on their first occurrence). - * - * @param array1 the first array (can be {@code null}). - * @param array2 the second array (can be {@code null}). - * - * @return the new array ({@code null} if both given arrays were {@code null}). - */ - public static String[] mergeStringArrays(String[] array1, String[] array2) { - if (ObjectUtils.isEmpty(array1)) { - return array2; - } - if (ObjectUtils.isEmpty(array2)) { - return array1; - } - - List result = new ArrayList(); - result.addAll(Arrays.asList(array1)); - for (String str: array2) { - if (!result.contains(str)) { - result.add(str); - } - } - return toStringArray(result); - } - - /** - * Turn given source {@code String} array into sorted array. - * - * @param array the source array. - * - * @return the sorted array (never {@code null}). - */ - public static String[] sortStringArray(String[] array) { - if (ObjectUtils.isEmpty(array)) { - return new String[0]; - } - - Arrays.sort(array); - return array; - } - - /** - * Copy the given {@code Collection} into a {@code String} array.

The {@code Collection} must contain {@code - * String} elements only. - * - * @param collection the {@code Collection} to copy. - * - * @return the {@code String} array. - */ - public static String[] toStringArray(Collection collection) { - if (collection == null) { - return null; - } - - return collection.toArray(new String[collection.size()]); - } - - /** - * Copy the given Enumeration into a {@code String} array. The Enumeration must contain {@code String} elements - * only. - * - * @param enumeration the Enumeration to copy. - * - * @return the {@code String} array. - */ - public static String[] toStringArray(Enumeration enumeration) { - if (enumeration == null) { - return null; - } - - List list = Collections.list(enumeration); - return list.toArray(new String[list.size()]); - } - - /** - * Trim the elements of the given {@code String} array, calling {@code String.trim()} on each of them. - * - * @param array the original {@code String} array. - * - * @return the resulting array (of the same size) with trimmed elements. - */ - public static String[] trimArrayElements(String[] array) { - if (ObjectUtils.isEmpty(array)) { - return new String[0]; - } - - String[] result = new String[array.length]; - for (int i = 0; i < array.length; i++) { - String element = array[i]; - result[i] = (element != null ? element.trim() : null); - } - return result; - } - - /** - * Remove duplicate strings from the given array. - * - *

As of 4.2, it preserves the original order, as it uses a {@link LinkedHashSet}. - * - * @param array the {@code String} array. - * - * @return an array without duplicates, in natural sort order. - */ - public static String[] removeDuplicateStrings(String[] array) { - if (ObjectUtils.isEmpty(array)) { - return array; - } - - Set set = new LinkedHashSet<>(); - for (String element: array) { - set.add(element); - } - return toStringArray(set); - } - - /** - * Split a {@code String} at the first occurrence of the delimiter. Does not include the delimiter in the result. - * - * @param toSplit the string to split. - * @param delimiter to split the string up with. - * - * @return a two element array with index 0 being before the delimiter, and index 1 being after the delimiter - * (neither element includes the delimiter); or {@code null} if the delimiter wasn't found in the given input - * {@code String}. - */ - public static String[] split(String toSplit, String delimiter) { - if (!hasLength(toSplit) || !hasLength(delimiter)) { - return null; - } - int offset = toSplit.indexOf(delimiter); - if (offset < 0) { - return null; - } - - String beforeDelimiter = toSplit.substring(0, offset); - String afterDelimiter = toSplit.substring(offset + delimiter.length()); - return new String[] {beforeDelimiter, afterDelimiter}; - } - - /** - * Take an array of strings and split each element based on the given delimiter. StandardCookieProcessor {@code - * Properties} instance is then generated, with the left of the delimiter providing the key, and the right of the - * delimiter providing the value. - * - *

Will trim both the key and value before adding them to the {@code Properties} instance. - * - * @param array the array to process. - * @param delimiter to split each element using (typically the equals symbol). - * - * @return a {@code Properties} instance representing the array contents, or {@code null} if the array to process - * was {@code null} or empty. - */ - public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) { - return splitArrayElementsIntoProperties(array, delimiter, null); - } - - /** - * Take an array of strings and split each element based on the given delimiter. StandardCookieProcessor {@code - * Properties} instance is then generated, with the left of the delimiter providing the key, and the right of the - * delimiter providing the value. - * - *

Will trim both the key and value before adding them to the {@code Properties} instance. - * - * @param array the array to process. - * @param delimiter to split each element using (typically the equals symbol). - * @param charsToDelete one or more characters to remove from each element prior to attempting the split - * operation (typically the quotation mark symbol), or {@code null} if no removal should occur. - * - * @return a {@code Properties} instance representing the array contents, or {@code null} if the array to process - * was {@code null} or empty. - */ - public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter, String charsToDelete) { - - if (ObjectUtils.isEmpty(array)) { - return null; - } - - Properties result = new Properties(); - for (String element: array) { - if (charsToDelete != null) { - element = deleteAny(element, charsToDelete); - } - String[] splittedElement = split(element, delimiter); - if (splittedElement == null) { - continue; - } - result.setProperty(splittedElement[0].trim(), splittedElement[1].trim()); - } - return result; - } - - /** - * Tokenize the given {@code String} into a {@code String} array via a {@link StringTokenizer}.

Trims tokens and - * omits empty tokens. - *

The given {@code delimiters} string can consist of any number of delimiter characters. Each of those - * characters - * can be used to separate tokens. StandardCookieProcessor delimiter is always a single character; for - * multi-character delimiters, consider using {@link #delimitedListToStringArray}. - * - * @param str the {@code String} to tokenize. - * @param delimiters the delimiter characters, assembled as a {@code String} (each of the characters is - * individually considered as a delimiter). - * - * @return an array of the tokens. - * - * @see StringTokenizer - * @see String#trim() - * @see #delimitedListToStringArray - */ - public static String[] tokenizeToStringArray(String str, String delimiters) { - return tokenizeToStringArray(str, delimiters, true, true); - } - - /** - * Tokenize the given {@code String} into a {@code String} array via a {@link StringTokenizer}.

The given {@code - * delimiters} string can consist of any number of delimiter characters. Each of those characters can be used to - * separate tokens. StandardCookieProcessor delimiter is always a single character; for multi-character delimiters, - * consider using {@link #delimitedListToStringArray}. - * - * @param str the {@code String} to tokenize. - * @param delimiters the delimiter characters, assembled as a {@code String} (each of the characters is - * individually considered as a delimiter). - * @param trimTokens trim the tokens via {@link String#trim()}. - * @param ignoreEmptyTokens omit empty tokens from the result array (only applies to tokens that are empty after - * trimming; StringTokenizer will not consider subsequent delimiters as token in the first place). - * - * @return an array of the tokens. - * - * @see StringTokenizer - * @see String#trim() - * @see #delimitedListToStringArray - */ - public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, - boolean ignoreEmptyTokens) { - - if (str == null) { - return null; - } - - StringTokenizer st = new StringTokenizer(str, delimiters); - List tokens = new ArrayList<>(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (trimTokens) { - token = token.trim(); - } - if (!ignoreEmptyTokens || token.length() > 0) { - tokens.add(token); - } - } - return toStringArray(tokens); - } - - /** - * Take a {@code String} that is a delimited list and convert it into a {@code String} array. - *

StandardCookieProcessor single {@code delimiter} may consist of more than one character, but it will still be - * considered as a single delimiter string, rather than as bunch of potential delimiter characters, in contrast to - * {@link #tokenizeToStringArray}. - * - * @param str the input {@code String}. - * @param delimiter the delimiter between elements (this is a single delimiter, rather than a bunch individual - * delimiter characters). - * - * @return an array of the tokens in the list. - * - * @see #tokenizeToStringArray - */ - public static String[] delimitedListToStringArray(String str, String delimiter) { - return delimitedListToStringArray(str, delimiter, null); - } - - /** - * Take a {@code String} that is a delimited list and convert it into a {@code String} array. - *

StandardCookieProcessor single {@code delimiter} may consist of more than one character, but it will still be - * considered as a single delimiter string, rather than as bunch of potential delimiter characters, in contrast to - * {@link #tokenizeToStringArray}. - * - * @param str the input {@code String}. - * @param delimiter the delimiter between elements (this is a single delimiter, rather than a bunch individual - * delimiter characters). - * @param charsToDelete a set of characters to delete; useful for deleting unwanted line breaks: e.g. "\r\n\f" - * will delete all new lines and line feeds in a {@code String}. - * - * @return an array of the tokens in the list. - * - * @see #tokenizeToStringArray - */ - public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { - if (str == null) { - return new String[0]; - } - if (delimiter == null) { - return new String[] {str}; - } - - List result = new ArrayList(); - if ("".equals(delimiter)) { - for (int i = 0; i < str.length(); i++) { - result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); - } - } else { - int pos = 0; - int delPos; - while ((delPos = str.indexOf(delimiter, pos)) != -1) { - result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); - pos = delPos + delimiter.length(); - } - if (str.length() > 0 && pos <= str.length()) { - // Add rest of String, but not in case of empty input. - result.add(deleteAny(str.substring(pos), charsToDelete)); - } - } - return toStringArray(result); - } - - /** - * Convert a comma delimited list (e.g., a row from a CSV file) into an array of strings. - * - * @param str the input {@code String}. - * - * @return an array of strings, or the empty array in case of empty input. - */ - public static String[] commaDelimitedListToStringArray(String str) { - return delimitedListToStringArray(str, ","); - } - - /** - * Convert a comma delimited list (e.g., a row from a CSV file) into a set.

Note that this will suppress - * duplicates, and as of 4.2, the elements in the returned set will preserve the original order in a {@link - * LinkedHashSet}. - * - * @param str the input {@code String}. - * - * @return a set of {@code String} entries in the list. - * - * @see #removeDuplicateStrings(String[]) - */ - public static Set commaDelimitedListToSet(String str) { - Set set = new LinkedHashSet(); - String[] tokens = commaDelimitedListToStringArray(str); - for (String token: tokens) { - set.add(token); - } - return set; - } - - /** - * Convert a {@link Collection} to a delimited {@code String} (e.g. CSV).

Useful for {@code toString()} - * implementations. - * - * @param coll the {@code Collection} to convert. - * @param delim the delimiter to use (typically a ","). - * @param prefix the {@code String} to start each element with. - * @param suffix the {@code String} to end each element with. - * - * @return the delimited {@code String} - */ - public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) { - if (coll == null || coll.isEmpty()) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - Iterator it = coll.iterator(); - while (it.hasNext()) { - sb.append(prefix).append(it.next()).append(suffix); - if (it.hasNext()) { - sb.append(delim); - } - } - return sb.toString(); - } - - /** - * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV).

Useful for {@code toString()} - * implementations. - * - * @param coll the {@code Collection} to convert. - * @param delim the delimiter to use (typically a ","). - * - * @return the delimited {@code String}. - */ - public static String collectionToDelimitedString(Collection coll, String delim) { - return collectionToDelimitedString(coll, delim, "", ""); - } - - /** - * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV).

Useful for {@code toString()} - * implementations. - * - * @param coll the {@code Collection} to convert. - * - * @return the delimited {@code String}. - */ - public static String collectionToCommaDelimitedString(Collection coll) { - return collectionToDelimitedString(coll, ","); - } - - /** - * Convert a {@code String} array into a delimited {@code String} (e.g. CSV).

Useful for {@code toString()} - * implementations. - * - * @param arr the array to display. - * @param delim the delimiter to use (typically a ","). - * - * @return the delimited {@code String}. - */ - public static String arrayToDelimitedString(Object[] arr, String delim) { - if (ObjectUtils.isEmpty(arr)) { - return ""; - } - if (arr.length == 1) { - return ObjectUtils.nullSafeToString(arr[0]); - } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < arr.length; i++) { - if (i > 0) { - sb.append(delim); - } - sb.append(arr[i]); - } - return sb.toString(); - } - - /** - * Convert a {@code String} array into a comma delimited {@code String} (i.e., CSV).

Useful for {@code - * toString()} implementations. - * - * @param arr the array to display. - * - * @return the delimited {@code String}. - */ - public static String arrayToCommaDelimitedString(Object[] arr) { - return arrayToDelimitedString(arr, ","); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/TextUtils.java b/api/src/main/java/com/yanzhenjie/andserver/util/TextUtils.java deleted file mode 100644 index d96c69f11822e0e59b1d49ec98604dd9afd3a62a..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/TextUtils.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.. - * - * 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.util.Iterator; - - -public class TextUtils { - - /** - * Returns true if the string is null or 0-length. - * @param str the string to be examined - * @return true if str is null or zero length - */ - public static boolean isEmpty( CharSequence str) { - return str == null || str.length() == 0; - } - - /** - * Returns a string containing the tokens joined by delimiters. - * - * @param delimiter a CharSequence that will be inserted between the tokens. If null, the string - * "null" will be used as the delimiter. - * @param tokens an array objects to be joined. Strings will be formed from the objects by - * calling object.toString(). If tokens is null, a NullPointerException will be thrown. If - * tokens is an empty array, an empty string will be returned. - */ - public static String join(CharSequence delimiter, Object[] tokens) { - final int length = tokens.length; - if (length == 0) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - sb.append(tokens[0]); - for (int i = 1; i < length; i++) { - sb.append(delimiter); - sb.append(tokens[i]); - } - return sb.toString(); - } - - /** - * Returns a string containing the tokens joined by delimiters. - * - * @param delimiter a CharSequence that will be inserted between the tokens. If null, the string - * "null" will be used as the delimiter. - * @param tokens an array objects to be joined. Strings will be formed from the objects by - * calling object.toString(). If tokens is null, a NullPointerException will be thrown. If - * tokens is empty, an empty string will be returned. - */ - public static String join(CharSequence delimiter, Iterable tokens) { - final Iterator it = tokens.iterator(); - if (!it.hasNext()) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - sb.append(it.next()); - while (it.hasNext()) { - sb.append(delimiter); - sb.append(it.next()); - } - return sb.toString(); - } -} diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/ToastUtil.java b/api/src/main/java/com/yanzhenjie/andserver/util/ToastUtil.java deleted file mode 100644 index 5f5cc1c5f10cbcccee0aa0bc36a46b89cdb1ef9b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/ToastUtil.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.. - * - * 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 ohos.agp.colors.RgbColor; -import ohos.agp.components.DirectionalLayout; -import ohos.agp.components.Text; -import ohos.agp.components.element.ShapeElement; -import ohos.agp.utils.Color; -import ohos.agp.utils.LayoutAlignment; -import ohos.agp.window.dialog.ToastDialog; -import ohos.agp.window.service.DisplayAttributes; -import ohos.agp.window.service.DisplayManager; -import ohos.app.Context; - -public class ToastUtil { - public static final int LENGTH_LONG = 4000; - public static final int LENGTH_SHORT = 2000; - - public enum ToastLayout { - DEFAULT, - CENTER, - TOP, - BOTTOM, - } - - public static void showShort(Context mContext, String content) { - createTost(mContext, content, LENGTH_SHORT, ToastLayout.DEFAULT); - } - - public static void showLong(Context mContext, String content) { - createTost(mContext, content, LENGTH_LONG, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, String content) { - createTost(mContext, content, LENGTH_SHORT, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, String content, int duration) { - createTost(mContext, content, duration, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, String content, ToastLayout layout) { - createTost(mContext, content, LENGTH_SHORT, layout); - } - - public static void show(Context mContext, String content, int duration, ToastLayout layout) { - createTost(mContext, content, duration, layout); - } - - public static void showShort(Context mContext, int content) { - createTost(mContext, getString(mContext, content), LENGTH_SHORT, ToastLayout.DEFAULT); - } - - public static void showLong(Context mContext, int content) { - createTost(mContext, getString(mContext, content), LENGTH_LONG, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, int content) { - createTost(mContext, getString(mContext, content), LENGTH_SHORT, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, int content, int duration) { - createTost(mContext, getString(mContext, content), duration, ToastLayout.DEFAULT); - } - - public static void show(Context mContext, int content, ToastLayout layout) { - createTost(mContext, getString(mContext, content), LENGTH_SHORT, layout); - } - - public static void show(Context mContext, int content, int duration, ToastLayout layout) { - createTost(mContext, getString(mContext, content), duration, layout); - } - - private static void createTost(Context mContext, String content, int duration, ToastLayout layout) { - DirectionalLayout toastLayout = new DirectionalLayout(mContext); - DirectionalLayout.LayoutConfig textConfig = new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT); - Text text = new Text(mContext); - text.setText(content); - text.setTextColor(new Color(Color.getIntColor("#ffffff"))); - text.setPadding(vp2px(mContext, 16), vp2px(mContext, 4), vp2px(mContext, 16), vp2px(mContext, 4)); - text.setTextSize(vp2px(mContext, 12)); - text.setBackground(buildDrawableByColorRadius(Color.getIntColor("#70000000"), vp2px(mContext, 20))); - text.setLayoutConfig(textConfig); - toastLayout.addComponent(text); - int mLayout = LayoutAlignment.CENTER; - switch (layout) { - case TOP: - mLayout = LayoutAlignment.TOP; - break; - case BOTTOM: - mLayout = LayoutAlignment.BOTTOM; - break; - case CENTER: - mLayout = LayoutAlignment.CENTER; - break; - } - ToastDialog toastDialog = new ToastDialog(mContext); - toastDialog.setComponent(toastLayout); - toastDialog.setSize(DirectionalLayout.LayoutConfig.MATCH_CONTENT, DirectionalLayout.LayoutConfig.MATCH_CONTENT); - toastDialog.setAlignment(mLayout); - toastDialog.setTransparent(true); - toastDialog.setDuration(duration); - toastDialog.show(); - } - - - private static ohos.agp.components.element.Element buildDrawableByColorRadius(int color, float radius) { - ShapeElement drawable = new ShapeElement(); - drawable.setShape(0); - drawable.setRgbColor(RgbColor.fromArgbInt(color)); - drawable.setCornerRadius(radius); - return drawable; - } - - private static String getString(Context mContent, int resId) { - try { - return mContent.getResourceManager().getElement(resId).getString(); - } catch (Exception e) { - e.printStackTrace(); - } - return ""; - } - - private static int vp2px(Context context, float vp) { - DisplayAttributes attributes = DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes(); - return (int) (attributes.densityPixels * vp); - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/TypeWrapper.java b/api/src/main/java/com/yanzhenjie/andserver/util/TypeWrapper.java deleted file mode 100644 index dee21880a9dd74dca5b125be36e485f79c9daf7b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/TypeWrapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -public abstract class TypeWrapper { - - private final Type mType; - - public TypeWrapper() { - Type superClass = getClass().getGenericSuperclass(); - mType = ((ParameterizedType) superClass).getActualTypeArguments()[0]; - } - - public Type getType() { - return mType; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/URLUtil.java b/api/src/main/java/com/yanzhenjie/andserver/util/URLUtil.java deleted file mode 100644 index 914402b628182cacf5ba3c112ebbdf8b740fcafe..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/URLUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.. - * - * 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; - -public class URLUtil { - /** - * @return {@code true} if the url is an http: url. - */ - public static boolean isHttpUrl(String url) { - return (null != url) && - (url.length() > 6) && - url.substring(0, 7).equalsIgnoreCase("http://"); - } - - /** - * @return {@code true} if the url is an https: url. - */ - public static boolean isHttpsUrl(String url) { - return (null != url) && - (url.length() > 7) && - url.substring(0, 8).equalsIgnoreCase("https://"); - } - - /** - * @return {@code true} if the url is a network url. - */ - public static boolean isNetworkUrl(String url) { - if (url == null || url.length() == 0) { - return false; - } - return isHttpUrl(url) || isHttpsUrl(url); - } -} diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java b/api/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java deleted file mode 100644 index e1894bd5984e9ebe8646c939b917626557214bc7..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/UrlCoder.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 Zhenjie Yan on 2018/8/6. - */ -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/api/src/main/java/com/yanzhenjie/andserver/util/comparator/CompoundComparator.java b/api/src/main/java/com/yanzhenjie/andserver/util/comparator/CompoundComparator.java deleted file mode 100644 index 9aecd386be7c9ca3418a07f4760c4ebc0792d26b..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/comparator/CompoundComparator.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.comparator; - - -import com.yanzhenjie.andserver.util.Assert; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/7/11. - */ -public class CompoundComparator implements Comparator, Serializable { - - private final List comparators; - - - /** - * Construct a CompoundComparator with initially no Comparators. Clients must add at least one Comparator before - * calling the compare method or an IllegalStateException is thrown. - */ - public CompoundComparator() { - this.comparators = new ArrayList<>(); - } - - /** - * Construct a CompoundComparator from the Comparators in the provided array. - * - *

All Comparators will default to ascending sort order, unless they are InvertibleComparators. - * - * @param comparators the comparators to build into a compound comparator - * - * @see InvertibleComparator - */ - @SuppressWarnings("unchecked") - public CompoundComparator(Comparator... comparators) { - Assert.notNull(comparators, "Comparators must not be null"); - this.comparators = new ArrayList<>(comparators.length); - for (Comparator comparator : comparators) { - addComparator(comparator); - } - } - - - /** - * Add a Comparator to the end of the chain. - * - *

The Comparator will default to ascending sort order, unless it is a InvertibleComparator. - * - * @param comparator the Comparator to add to the end of the chain. - */ - @SuppressWarnings("unchecked") - public void addComparator(Comparator comparator) { - if (comparator instanceof InvertibleComparator) { - this.comparators.add((InvertibleComparator) comparator); - } else { - this.comparators.add(new InvertibleComparator(comparator)); - } - } - - /** - * Add a Comparator to the end of the chain using the provided sort order. - * - * @param comparator the Comparator to add to the end of the chain - * @param ascending the sort order: ascending (true) or descending (false) - */ - @SuppressWarnings("unchecked") - public void addComparator(Comparator comparator, boolean ascending) { - this.comparators.add(new InvertibleComparator(comparator, ascending)); - } - - /** - * Replace the Comparator at the given index.

The Comparator will default to ascending sort order, unless it is a - * InvertibleComparator. - * - * @param index the index of the Comparator to replace - * @param comparator the Comparator to place at the given index - * - * @see InvertibleComparator - */ - @SuppressWarnings("unchecked") - public void setComparator(int index, Comparator comparator) { - if (comparator instanceof InvertibleComparator) { - this.comparators.set(index, (InvertibleComparator) comparator); - } else { - this.comparators.set(index, new InvertibleComparator(comparator)); - } - } - - /** - * Replace the Comparator at the given index using the given sort order. - * - * @param index the index of the Comparator to replace - * @param comparator the Comparator to place at the given index - * @param ascending the sort order: ascending (true) or descending (false) - */ - public void setComparator(int index, Comparator comparator, boolean ascending) { - this.comparators.set(index, new InvertibleComparator<>(comparator, ascending)); - } - - /** - * Invert the sort order of each sort definition contained by this compound comparator. - */ - public void invertOrder() { - for (InvertibleComparator comparator : this.comparators) { - comparator.invertOrder(); - } - } - - /** - * Invert the sort order of the sort definition at the specified index. - * - * @param index the index of the comparator to invert - */ - public void invertOrder(int index) { - this.comparators.get(index).invertOrder(); - } - - /** - * Change the sort order at the given index to ascending. - * - * @param index the index of the comparator to change - */ - public void setAscendingOrder(int index) { - this.comparators.get(index).setAscending(true); - } - - /** - * Change the sort order at the given index to descending sort. - * - * @param index the index of the comparator to change - */ - public void setDescendingOrder(int index) { - this.comparators.get(index).setAscending(false); - } - - /** - * Returns the number of aggregated comparators. - */ - public int getComparatorCount() { - return this.comparators.size(); - } - - @SuppressWarnings("unchecked") - @Override - public int compare(T o1, T o2) { - String message = "No sort definitions have been added to this CompoundComparator to compare"; - Assert.state(this.comparators.size() > 0, message); - for (InvertibleComparator comparator : this.comparators) { - int result = comparator.compare(o1, o2); - if (result != 0) { - return result; - } - } - return 0; - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof CompoundComparator)) { - return false; - } - CompoundComparator other = (CompoundComparator) obj; - return this.comparators.equals(other.comparators); - } - - @Override - public int hashCode() { - return this.comparators.hashCode(); - } - - @Override - public String toString() { - return "CompoundComparator: " + this.comparators; - } -} \ No newline at end of file diff --git a/api/src/main/java/com/yanzhenjie/andserver/util/comparator/InvertibleComparator.java b/api/src/main/java/com/yanzhenjie/andserver/util/comparator/InvertibleComparator.java deleted file mode 100644 index 735056e9f829fb26f5b738705d4c9f7dff3fa0b3..0000000000000000000000000000000000000000 --- a/api/src/main/java/com/yanzhenjie/andserver/util/comparator/InvertibleComparator.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.comparator; - -import com.yanzhenjie.andserver.util.Assert; - -import java.io.Serializable; -import java.util.Comparator; - -/** - * Created by Zhenjie Yan on 2018/7/11. - */ -public class InvertibleComparator implements Comparator, Serializable { - - private final Comparator comparator; - - private boolean ascending = true; - - /** - * Create an InvertibleComparator that sorts ascending by default. For the actual comparison, the specified - * Comparator will be used. - * - * @param comparator the comparator to decorate. - */ - public InvertibleComparator(Comparator comparator) { - Assert.notNull(comparator, "Comparator must not be null."); - this.comparator = comparator; - } - - /** - * Create an InvertibleComparator that sorts based on the provided order. For the actual comparison, the specified - * Comparator will be used. - * - * @param comparator the comparator to decorate. - * @param ascending the sort order: ascending (true) or descending (false). - */ - public InvertibleComparator(Comparator comparator, boolean ascending) { - Assert.notNull(comparator, "Comparator must not be null."); - this.comparator = comparator; - setAscending(ascending); - } - - /** - * Specify the sort order: ascending (true) or descending (false). - */ - public void setAscending(boolean ascending) { - this.ascending = ascending; - } - - /** - * Return the sort order: ascending (true) or descending (false). - */ - public boolean isAscending() { - return this.ascending; - } - - /** - * Invert the sort order: ascending -> descending or descending -> ascending. - */ - public void invertOrder() { - this.ascending = !this.ascending; - } - - @Override - public int compare(T o1, T o2) { - int result = this.comparator.compare(o1, o2); - if (result != 0) { - // Invert the order if it is a reverse sort. - if (!this.ascending) { - if (Integer.MIN_VALUE == result) { - result = Integer.MAX_VALUE; - } else { - result *= -1; - } - } - return result; - } - return 0; - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof InvertibleComparator)) { - return false; - } - InvertibleComparator other = (InvertibleComparator) obj; - return (this.comparator.equals(other.comparator) && this.ascending == other.ascending); - } - - @Override - public int hashCode() { - return this.comparator.hashCode(); - } - - @Override - public String toString() { - return "InvertibleComparator: [" + this.comparator + "]; ascending=" + this.ascending; - } -} \ No newline at end of file diff --git a/api/src/main/resources/base/element/string.json b/api/src/main/resources/base/element/string.json deleted file mode 100644 index 18ff170a8b3f23686cf70c7ffd159a645ea95b6b..0000000000000000000000000000000000000000 --- a/api/src/main/resources/base/element/string.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "string": [ - { - "name": "app_name", - "value": "api" - } - ] -} diff --git a/build.gradle b/build.gradle index fa0982e0b0e3e4b27a986a728df526d1b262c1c3..161bf1e1126b7cc26b250a6a7424473840b11b25 100755 --- a/build.gradle +++ b/build.gradle @@ -20,14 +20,17 @@ buildscript { jcenter() } dependencies { - classpath 'com.huawei.ohos:hap:2.4.2.7' + classpath 'com.huawei.ohos:hap:2.4.4.2' classpath "com.yanzhenjie.andserver:plugin:2.1.7" - classpath 'com.huawei.ohos:decctest:1.0.0.6' + classpath 'com.huawei.ohos:decctest:1.0.0.7' } } allprojects { repositories { + maven { + url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + } maven { url 'https://mirrors.huaweicloud.com/repository/maven/' } diff --git a/entry/build.gradle b/entry/build.gradle index 3a58d12e67a66d463894ca422e7ee0aa8740f316..282e742778bceb28e927627758617e4a13c355c8 100644 --- a/entry/build.gradle +++ b/entry/build.gradle @@ -1,6 +1,12 @@ apply plugin: 'com.huawei.ohos.hap' apply plugin: 'com.yanzhenjie.andserver' +apply plugin: 'com.huawei.ohos.decctest' + ohos { + + signingConfigs { + + } compileSdkVersion 5 defaultConfig { compatibleSdkVersion 5 @@ -13,9 +19,12 @@ ohos { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) testCompile 'junit:junit:4.12' - api project(':api') - api project(':annotation') - annotationProcessor project(':processor') +// api project(':api') +// api project(':annotation') +// annotationProcessor project(':processor') + api 'com.gitee.chinasoft_ohos:AndserverApi:0.0.1-SNAPSHOT' + api 'com.gitee.chinasoft_ohos:AndserverAnnotation:0.0.1-SNAPSHOT' + annotationProcessor 'com.gitee.chinasoft_ohos:AndserverProcessor:0.0.1-SNAPSHOT' api 'org.apache.commons:commons-lang3:3.9' api 'com.alibaba:fastjson:1.1.71.android' implementation 'io.openharmony.tpc.thirdlib:floatingactionbutton:1.0.0' @@ -23,4 +32,6 @@ dependencies { implementation 'io.openharmony.tpc.thirdlib:EventBus:1.0.2' implementation 'io.openharmony.tpc.thirdlib:BGARefreshLayout-ohos:1.0.0' implementation 'io.openharmony.tpc.thirdlib:XPopup:1.0.3' + ohosTestImplementation 'com.huawei.ohos.testkit:runner:1.0.0.100' + } diff --git a/entry/src/main/config.json b/entry/src/main/config.json index 3ad619c202f37310b311c25c3467fdd7ba49b382..883cc695d70b81743d034dc46b73e6eb49e82590 100644 --- a/entry/src/main/config.json +++ b/entry/src/main/config.json @@ -3,11 +3,11 @@ "bundleName": "com.yanzhenjie.hos", "vendor": "yanzhenjie", "version": { - "code": 1, + "code": 1000000, "name": "1.0.0" }, "apiVersion": { - "compatible": 5, + "compatible": 4, "target": 5, "releaseType": "Release" } @@ -73,7 +73,7 @@ "name": "com.yanzhenjie.andserver.MainAbility", "icon": "$media:icon", "description": "$string:mainability_description", - "label": "FileTransfer", + "label": "$string:app_name", "type": "page", "launchType": "standard", "metaData": { diff --git a/entry/src/main/java/com/yanzhenjie/andserver/dialog/BottomDialog.java b/entry/src/main/java/com/yanzhenjie/andserver/dialog/BottomDialog.java index 4f804674c0415c7548f8b5fee8bb7e2d7c17f56c..78a99b3b54b44de88150c23817e2b817d2695ef9 100644 --- a/entry/src/main/java/com/yanzhenjie/andserver/dialog/BottomDialog.java +++ b/entry/src/main/java/com/yanzhenjie/andserver/dialog/BottomDialog.java @@ -35,8 +35,9 @@ package com.yanzhenjie.andserver.dialog; import com.shaohui.bottomdialog.BaseOsDiaLog; -import com.yanzhenjie.hos.ResourceTable; + +import com.yanzhenjie.hos.ResourceTable; import ohos.agp.components.Component; import ohos.agp.components.Text; import ohos.agp.utils.TextAlignment; diff --git a/entry/src/main/java/com/yanzhenjie/andserver/slice/MainAbilitySlice.java b/entry/src/main/java/com/yanzhenjie/andserver/slice/MainAbilitySlice.java index 43a2c2000a4dbdefc1fdb01b924374bf89e83598..afcfce640a6e2c04dc08b974c5388bf653fd02e1 100644 --- a/entry/src/main/java/com/yanzhenjie/andserver/slice/MainAbilitySlice.java +++ b/entry/src/main/java/com/yanzhenjie/andserver/slice/MainAbilitySlice.java @@ -6,9 +6,9 @@ import cn.bingoogolapple.refreshlayout.BgarefreshLayout; import com.github.clans.fab.FloatingActionButton; import com.lxj.xpopup.XPopup; -import com.lxj.xpopup.interfaces.OnConfirmListener; + import com.yanzhenjie.andserver.MyCommonEventSubscriber; -import com.yanzhenjie.andserver.dialog.BottomDialog; + import com.yanzhenjie.andserver.dialog.CustomAttachPopup2; import com.yanzhenjie.andserver.dialog.ZhihuCommentPopup; @@ -224,26 +224,26 @@ public class MainAbilitySlice extends AbilitySlice implements Component.ClickedL if (null != resultData.getParams()) { IntentParams parms = resultData.getParams(); - ArrayList pathlist=new ArrayList<>(); + ArrayList pathlist = new ArrayList<>(); String uri1 = null; - ArrayList urilist=new ArrayList<>(); - ArrayList filelist=new ArrayList<>(); + ArrayList urilist = new ArrayList<>(); + ArrayList filelist = new ArrayList<>(); for (String key : parms.keySet()) { - pathlist= (ArrayList) parms.getParam(key); + pathlist = (ArrayList) parms.getParam(key); } - for(int i=0; i { - - @Override - public void apply(Project project) { - Log.inject(project); - project.getPlugins().all(it -> { - if (it instanceof AppPlugin) { - AppExtension extension = project.getExtensions().getByType(AppExtension.class); - configGenerator(project, false, extension.getApplicationVariants()); - } else if (it instanceof LibraryPlugin) { - LibraryExtension extension = project.getExtensions().getByType(LibraryExtension.class); - configGenerator(project, true, extension.getLibraryVariants()); - } else if (it instanceof FeaturePlugin) { - FeatureExtension extension = project.getExtensions().getByType(FeatureExtension.class); - configGenerator(project, true, extension.getFeatureVariants()); - } - }); - } - - private void configGenerator(Project project, boolean library, DomainObjectSet variants) { - variants.all(it -> { - configTask(project, library, it.getApplicationId(), it.getFlavorName()); - File outputDir = new File(project.getBuildDir(), "generated/source/andServer/" + it.getDirName()); - String taskName = String.format("generate%sAppInfo", capitalize(it.getName())); - Task generate = project.getTasks().create(taskName, AppInfoGenerator.class, generator -> { - generator.setOutputDir(outputDir); - String appId = it.getApplicationId(); - generator.setAppId(appId); - String packageName = String.format("%s.andserver.plugin.generator", appId); - generator.setPackageName(packageName); - }); - it.registerJavaGeneratingTask(generate, outputDir); - }); - } - - private void configTask(Project project, boolean library, String appId, String flavorName) { - Action action = task -> { - String taskName = task.getName(); - String moduleType = String.format("%s_assets", library ? "library" : "merged"); - String buildType = generateBuildType(taskName, flavorName); - String path = String.format("./intermediates/%s/%s/out", moduleType, buildType); - - File dir = new File(project.getBuildDir(), path); - if (!dir.exists()) { - dir.mkdirs(); - } - - String filename = String.format("%s.andserver", appId); - File file = new File(dir, filename); - if (!file.exists()) { - try { - file.createNewFile(); - FileUtils.write(file, filename); - } catch (IOException e) { - e.printStackTrace(); - } - } - }; - - project.getTasks().getByName(String.format("%s%sReleaseAssets", library ? "package" : "merge", capitalize(flavorName))).doLast(action); - project.getTasks().getByName(String.format("%s%sDebugAssets", library ? "package" : "merge", capitalize(flavorName))).doLast(action); - } - - private String generateBuildType(String taskName, String flavorName) { - if (flavorName == null || flavorName.length() == 0) { - return taskName.toLowerCase().contains("debug") ? "debug" : "release"; - } - - return taskName.toLowerCase().contains("debug") ? String.format("%sDebug", flavorName) : String.format("%sRelease", flavorName); - } - - public static String capitalize(String text) { - if (text != null && text.length() > 0) { - char[] chars = text.toCharArray(); - chars[0] = Character.toUpperCase(chars[0]); - return new String(chars); - } - return text; - } -} \ No newline at end of file diff --git a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/AppInfoGenerator.java b/plugin/src/main/java/com/yanzhenjie/andserver/plugin/AppInfoGenerator.java deleted file mode 100644 index d2dc7b59128d1469257e0fb10a042a6caed18b76..0000000000000000000000000000000000000000 --- a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/AppInfoGenerator.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.plugin; - -import com.squareup.javapoet.AnnotationSpec; -import com.squareup.javapoet.JavaFile; -import com.squareup.javapoet.TypeSpec; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.plugin.util.Constants; -import org.apache.commons.io.FileUtils; -import org.gradle.api.DefaultTask; -import org.gradle.api.tasks.TaskAction; - -import javax.lang.model.element.Modifier; -import java.io.File; -import java.util.Random; - -/** - * Created by Zhenjie Yan on 4/11/20. - */ -public class AppInfoGenerator extends DefaultTask { - - private static final char[] CHARS = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; - - private File outputDir; - private String appId; - private String packageName; - - public AppInfoGenerator() { - } - - public void setOutputDir(File outputDir) { - this.outputDir = outputDir; - } - - public void setAppId(String appId) { - this.appId = appId; - } - - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - @TaskAction - public void generate() throws Exception { - FileUtils.deleteDirectory(outputDir); - - Random random = new Random(); - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < 10; i++) { - int index = random.nextInt(CHARS.length); - builder.append(CHARS[index]); - } - - AnnotationSpec annotation = AnnotationSpec.builder(AppInfo.class) - .addMember("value", "$S", appId) - .build(); - - TypeSpec adapterClass = TypeSpec.classBuilder(AndServerPlugin.capitalize(builder.toString())) - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addAnnotation(annotation) - .build(); - - JavaFile javaFile = JavaFile.builder(packageName, adapterClass).build(); - javaFile.writeTo(outputDir); - } - -} \ No newline at end of file diff --git a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Constants.java b/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Constants.java deleted file mode 100644 index 206cb10343173d4ae0a9cec99651dfb88857c590..0000000000000000000000000000000000000000 --- a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Constants.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.plugin.util; - -/** - * Created by Zhenjie Yan on 4/11/20. - */ -public interface Constants { - - String DOC_EDIT_WARN = "This file was generated by AndServer automatically and you should NOT edit it."; -} \ No newline at end of file diff --git a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Log.java b/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Log.java deleted file mode 100644 index e50676937d7680155189359aa1e04396661bbdc3..0000000000000000000000000000000000000000 --- a/plugin/src/main/java/com/yanzhenjie/andserver/plugin/util/Log.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.plugin.util; - -import org.gradle.api.Project; - -/** - * Created by Zhenjie Yan on 4/10/20. - */ -public class Log { - - private static org.gradle.api.logging.Logger sLogger; - - public static void inject(Project project) { - sLogger = project.getLogger(); - } - - public Log() { - } - - public void i(String format, Object... args) { - if (null != format && null != sLogger) { - sLogger.info("AndServer::Info >>> " + String.format(format, args)); - } - } - - public void d(String format, Object... args) { - if (null != format && null != sLogger) { - sLogger.debug("AndServer::Debug >>> " + String.format(format, args)); - } - } - - public void w(String format, Object... args) { - if (null != format && null != sLogger) { - sLogger.warn("AndServer::Warn >>> " + String.format(format, args)); - } - } - - public void e(String format, Object... args) { - if (null != format && null != sLogger) { - sLogger.error("AndServer::Error >>> " + String.format(format, args)); - } - } - - public void e(Throwable error) { - if (null != error) { - sLogger.error("AndServer::Error >>> " + formatStackTrace(error.getStackTrace())); - } - } - - private static 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/processor/.gitignore b/processor/.gitignore deleted file mode 100644 index 796b96d1c402326528b4ba3c12ee9d92d0e212e9..0000000000000000000000000000000000000000 --- a/processor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/processor/build.gradle b/processor/build.gradle deleted file mode 100644 index 3669a9b3f280daaf19223337e1af16737f1acdea..0000000000000000000000000000000000000000 --- a/processor/build.gradle +++ /dev/null @@ -1,18 +0,0 @@ -apply plugin: 'java-library' - -dependencies { - api project(':annotation') - implementation fileTree(dir: 'libs', include: ['*.jar']) - api 'com.squareup:javapoet:1.12.1' - api 'org.apache.commons:commons-collections4:4.4' - api 'org.apache.commons:commons-lang3:3.9' - implementation 'com.google.auto.service:auto-service:1.0-rc6' - annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6' -} - -sourceCompatibility = "8" -targetCompatibility = "8" - -ohos { - compileSdkVersion = 5 -} diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java deleted file mode 100644 index f20e343baff5f439cc68190f673a7fa04a78fa44..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/BaseProcessor.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.squareup.javapoet.TypeName; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.annotation.RestController; - -import javax.annotation.processing.AbstractProcessor; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import java.lang.annotation.Annotation; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * Created by Zhenjie Yan 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); - - protected boolean isAcceptType(TypeElement element, TypeName type) { - TypeMirror mirror = element.getSuperclass(); - if (mirror == null || mirror.getKind() != TypeKind.DECLARED) { - return false; - } - if (type.equals(TypeName.get(mirror))) { - return true; - } - - if (mirror instanceof DeclaredType) { - Element parent = ((DeclaredType) mirror).asElement(); - if (parent instanceof TypeElement) { - return isAcceptType((TypeElement) parent, type); - } - } - return false; - } - - protected boolean isAcceptInterface(TypeElement element, TypeName type) { - List mirrors = element.getInterfaces(); - - for (TypeMirror mirror : mirrors) { - if (type.equals(TypeName.get(mirror))) { - return true; - } - } - - TypeMirror mirror = element.getSuperclass(); - if (mirror == null || mirror.getKind() != TypeKind.DECLARED) { - return false; - } - - if (mirror instanceof DeclaredType) { - Element parent = ((DeclaredType) mirror).asElement(); - if (parent instanceof TypeElement) { - return isAcceptInterface((TypeElement) parent, type); - } - } - return false; - } - protected String getRegisterPackageName(Set appSet) { - List list = appSet.stream() - .map((Function) element -> { - AppInfo appInfo = element.getAnnotation(AppInfo.class); - return appInfo == null ? null : appInfo.value(); - }) - .collect(Collectors.toList()); - if (list.size() <= 0) { - throw new RuntimeException(PLUGIN_MESSAGE); - } - String rootPackage = list.get(0); - return String.format("%s.%s", rootPackage, "andserver.processor.generator"); - } - - private static final String PLUGIN_MESSAGE = "\nAdd the plugin to your project build script :" - + "\nbuildscript {" - + "\n repositories {" - + "\n mavenCentral()" - + "\n google()" - + "\n }" - + "\n dependencies {" - + "\n classpath 'com.yanzhenjie.andserver:plugin:{version}'" - + "\n ..." - + "\n }" - + "\n}\n" - + "\nAnd then apply it in your module:" - + "\napply plugin: 'com.yanzhenjie.andserver'"; -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/ConfigProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/ConfigProcessor.java deleted file mode 100644 index d8f74c86309d6130e1b8a887a9afd843f78d46bb..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/ConfigProcessor.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright © 2019 Zhenjie Yan. - * - * 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 com.google.auto.service.AutoService; -import com.squareup.javapoet.*; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.annotation.Config; -import com.yanzhenjie.andserver.processor.util.Constants; -import com.yanzhenjie.andserver.processor.util.Logger; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.Validate; - -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Created by Zhenjie Yan on 2019-06-29. - *

- * @Config
- * public class AppConfig implements WebConfig {
- *
- *     @Override
- *     public void onConfig(Context context, Delegate delegate) {
- *         Website website = ...;
- *         delegate.addWebsite(website);
- *
- *         Multipart multipart = Multipart.newBuilder()...build();
- *         delegate.setMultipart(multipart);
- *     }
- * }
- * 
- */ -//@AutoService(Processor.class) -//@SupportedSourceVersion(SourceVersion.RELEASE_8) -//@SupportedAnnotationTypes({"com.yanzhenjie.andserver.annotation.Config","com.yanzhenjie.andserver.annotation.AppInfo"}) -public class ConfigProcessor extends BaseProcessor { - - private Filer mFiler; - private Elements mElements; - private Logger mLog; - - private TypeName mContext; - private TypeName mOnRegisterType; - private TypeName mRegisterType; - - private TypeName mConfig; - private TypeName mDelegate; - private TypeName mWebsite; - private TypeName mMultipart; - - private TypeName mString; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - mFiler = processingEnv.getFiler(); - mElements = processingEnv.getElementUtils(); - mLog = new Logger(processingEnv.getMessager()); - - mContext = TypeName.get(mElements.getTypeElement(Constants.CONTEXT_TYPE).asType()); - mOnRegisterType = TypeName.get(mElements.getTypeElement(Constants.ON_REGISTER_TYPE).asType()); - mRegisterType = TypeName.get(mElements.getTypeElement(Constants.REGISTER_TYPE).asType()); - - mConfig = TypeName.get(mElements.getTypeElement(Constants.CONFIG_TYPE).asType()); - mDelegate = TypeName.get(mElements.getTypeElement(Constants.CONFIG_DELEGATE_TYPE).asType()); - mWebsite = TypeName.get(mElements.getTypeElement(Constants.WEBSITE_TYPE).asType()); - mMultipart = TypeName.get(mElements.getTypeElement(Constants.CONFIG_MULTIPART_TYPE).asType()); - - mString = TypeName.get(String.class); - } - - @Override - public boolean process(Set set, RoundEnvironment roundEnv) { - if (CollectionUtils.isEmpty(set)) { - return false; - } - - Set appSet = roundEnv.getElementsAnnotatedWith(AppInfo.class); - String registerPackageName = getRegisterPackageName(appSet); - Map configMap = findAnnotation(roundEnv); - createRegister(registerPackageName, configMap); - return true; - } - - private Map findAnnotation(RoundEnvironment roundEnv) { - Set set = roundEnv.getElementsAnnotatedWith(Config.class); - Map configMap = new HashMap<>(); - - for (Element element: set) { - if (element instanceof TypeElement) { - TypeElement typeElement = (TypeElement) element; - Set modifiers = typeElement.getModifiers(); - Validate.isTrue(modifiers.contains(Modifier.PUBLIC), "The modifier public is missing on %s.", - typeElement.getQualifiedName()); - - List interfaces = typeElement.getInterfaces(); - if (CollectionUtils.isEmpty(interfaces)) { - mLog.w(String.format("The annotation Converter must be used in a subclass of [WebConfig] on %s.", - typeElement.getQualifiedName())); - continue; - } - for (TypeMirror typeMirror: interfaces) { - if (mConfig.equals(TypeName.get(typeMirror))) { - configMap.put(getGroup(typeElement), typeElement); - break; - } else { - mLog.w(String.format("The annotation Config must be used in a subclass of [WebConfig] on %s.", - typeElement.getQualifiedName())); - } - } - } - } - return configMap; - } - - private void createRegister(String registerPackageName, Map configMap) { - TypeName typeName = ParameterizedTypeName.get(ClassName.get(Map.class), mString, mConfig); - FieldSpec mapField = FieldSpec.builder(typeName, "mMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder().addStatement("this.mMap = new $T<>()", HashMap.class); - for (Map.Entry entry: configMap.entrySet()) { - String group = entry.getKey(); - TypeElement config = entry.getValue(); - mLog.i(String.format("------ Processing %s ------", config.getSimpleName())); - rootCode.addStatement("this.mMap.put($S, new $T())", group, config); - } - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - TypeName listType = ParameterizedTypeName.get(ClassName.get(List.class), mWebsite); - - MethodSpec registerMethod = MethodSpec.methodBuilder("onRegister") - .addAnnotation(Override.class) - .addModifiers(Modifier.PUBLIC) - .addParameter(mContext, "context") - .addParameter(mString, "group") - .addParameter(mRegisterType, "register") - .addStatement("$T config = mMap.get(group)", mConfig) - .beginControlFlow("if(config == null)") - .addStatement("config = mMap.get($S)", "default") - .endControlFlow() - .beginControlFlow("if(config != null)") - .addStatement("$T delegate = $T.newInstance()", mDelegate, mDelegate) - .addStatement("config.onConfig(context, delegate)") - .addStatement("$T list = delegate.getWebsites()", listType) - .beginControlFlow("if(list != null && !list.isEmpty())") - .beginControlFlow("for ($T website : list)", mWebsite) - .addStatement("register.addAdapter(website)") - .endControlFlow() - .endControlFlow() - .addStatement("$T multipart = delegate.getMultipart()", mMultipart) - .addStatement("register.setMultipart(multipart)") - .endControlFlow() - .build(); - - TypeSpec adapterClass = TypeSpec.classBuilder("ConfigRegister") - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addSuperinterface(mOnRegisterType) - .addField(mapField) - .addMethod(rootMethod) - .addMethod(registerMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(registerPackageName, adapterClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String getGroup(TypeElement type) { - Config config = type.getAnnotation(Config.class); - if (config != null) { - return config.value(); - } - throw new IllegalStateException(String.format("The type is not a Config: %1$s.", type)); - } - - @Override - protected void addAnnotation(Set> classSet) { - classSet.add(Config.class); - classSet.add(AppInfo.class); - } -} diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/ControllerProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/ControllerProcessor.java deleted file mode 100644 index fee86160a1e62744b9705afa3323d3d84522fe3b..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/ControllerProcessor.java +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.google.auto.service.AutoService; -import com.squareup.javapoet.*; -import com.yanzhenjie.andserver.annotation.*; -import com.yanzhenjie.andserver.processor.cross.CrossOriginImpl; -import com.yanzhenjie.andserver.processor.cross.MergeCrossOrigin; -import com.yanzhenjie.andserver.processor.mapping.*; -import com.yanzhenjie.andserver.processor.util.Constants; -import com.yanzhenjie.andserver.processor.util.Logger; -import com.yanzhenjie.andserver.processor.util.Patterns; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Validate; - -import javax.activation.MimeType; -import javax.activation.MimeTypeParseException; -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.*; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.*; -import java.util.regex.Pattern; - -/** - * Created by Zhenjie Yan on 2018/6/8. - */ -//@AutoService(Processor.class) -//@SupportedSourceVersion(SourceVersion.RELEASE_8) -//@SupportedAnnotationTypes({"com.yanzhenjie.andserver.annotation.Controller","com.yanzhenjie.andserver.annotation.Controller.RestController", -// "com.yanzhenjie.andserver.annotation.RequestMapping","com.yanzhenjie.andserver.annotation.GetMapping","com.yanzhenjie.andserver.annotation.PostMapping", -// "com.yanzhenjie.andserver.annotation.PutMapping","com.yanzhenjie.andserver.annotation.PatchMapping","com.yanzhenjie.andserver.annotation.DeleteMapping", -// "com.yanzhenjie.andserver.annotation.CrossOrigin","com.yanzhenjie.andserver.annotation.Addition", -// "com.yanzhenjie.andserver.annotation.ResponseBody","com.yanzhenjie.andserver.annotation.QueryParam", -// "com.yanzhenjie.andserver.annotation.RequestParam","com.yanzhenjie.andserver.annotation.FormPart","com.yanzhenjie.andserver.annotation.AppInfo"}) -public class ControllerProcessor extends BaseProcessor implements Patterns { - - private Filer mFiler; - private Elements mElements; - private Logger mLog; - - private TypeName mContext; - private TypeName mTextUtils; - private ClassName mTypeWrapper; - private TypeName mMediaType; - private TypeName mOnRegisterType; - private TypeName mRegisterType; - - private TypeName mBodyMissing; - private TypeName mCookieMissing; - private TypeName mParamMissing; - private TypeName mHeaderMissing; - private TypeName mPathMissing; - private TypeName mParamError; - - private TypeName mAdapter; - private TypeName mMappingAdapter; - private TypeName mHandler; - private TypeName mMappingHandler; - private TypeName mView; - private TypeName mViewObject; - private TypeName mConverter; - - private TypeName mRequest; - private TypeName mMultipartRequest; - private TypeName mResponse; - private TypeName mHttpMethod; - private TypeName mHttpHeaders; - private TypeName mSession; - private TypeName mRequestBody; - private TypeName mMultipartFile; - private TypeName mMultipartFileArray; - private TypeName mMultipartFileList; - - private TypeName mAddition; - private TypeName mCrossOrigin; - private TypeName mMapping; - private TypeName mMimeTypeMapping; - private TypeName mMethodMapping; - private TypeName mPairMapping; - private TypeName mPathMapping; - private TypeName mMappingList; - - private TypeName mString = TypeName.get(String.class); - private ArrayTypeName mStringArray = ArrayTypeName.of(String.class); - private ArrayTypeName mIntArray = ArrayTypeName.of(int.class); - private ArrayTypeName mLongArray = ArrayTypeName.of(long.class); - private ArrayTypeName mFloatArray = ArrayTypeName.of(float.class); - private ArrayTypeName mDoubleArray = ArrayTypeName.of(double.class); - private ArrayTypeName mBooleanArray = ArrayTypeName.of(boolean.class); - - private TypeName mStringList = ParameterizedTypeName.get(ClassName.get(List.class), mString); - - private List mHashCodes = new ArrayList<>(); - - private Pattern mBlurredPathPattern = Pattern.compile(PATH_BLURRED_INCLUDE); - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - mFiler = processingEnv.getFiler(); - mElements = processingEnv.getElementUtils(); - mLog = new Logger(processingEnv.getMessager()); - - mContext = TypeName.get(mElements.getTypeElement(Constants.CONTEXT_TYPE).asType()); - mTextUtils = TypeName.get(mElements.getTypeElement(Constants.TEXT_UTILS_TYPE).asType()); - mTypeWrapper = ClassName.get(mElements.getTypeElement(Constants.TYPE_WRAPPER_TYPE)); - mMediaType = TypeName.get(mElements.getTypeElement(Constants.MEDIA_TYPE).asType()); - mOnRegisterType = TypeName.get(mElements.getTypeElement(Constants.ON_REGISTER_TYPE).asType()); - mRegisterType = TypeName.get(mElements.getTypeElement(Constants.REGISTER_TYPE).asType()); - - mBodyMissing = TypeName.get(mElements.getTypeElement(Constants.BODY_MISSING).asType()); - mCookieMissing = TypeName.get(mElements.getTypeElement(Constants.COOKIE_MISSING).asType()); - mParamMissing = TypeName.get(mElements.getTypeElement(Constants.PARAM_MISSING).asType()); - mHeaderMissing = TypeName.get(mElements.getTypeElement(Constants.HEADER_MISSING).asType()); - mPathMissing = TypeName.get(mElements.getTypeElement(Constants.PATH_MISSING).asType()); - mParamError = TypeName.get(mElements.getTypeElement(Constants.PARAM_ERROR).asType()); - - mConverter = TypeName.get(mElements.getTypeElement(Constants.CONVERTER_TYPE).asType()); - mAdapter = TypeName.get(mElements.getTypeElement(Constants.ADAPTER_TYPE).asType()); - mMappingAdapter = TypeName.get(mElements.getTypeElement(Constants.MAPPING_ADAPTER_TYPE).asType()); - mHandler = TypeName.get(mElements.getTypeElement(Constants.HANDLER_TYPE).asType()); - mMappingHandler = TypeName.get(mElements.getTypeElement(Constants.MAPPING_HANDLER_TYPE).asType()); - mView = TypeName.get(mElements.getTypeElement(Constants.VIEW_TYPE).asType()); - mViewObject = TypeName.get(mElements.getTypeElement(Constants.VIEW_TYPE_OBJECT).asType()); - - mRequest = TypeName.get(mElements.getTypeElement(Constants.REQUEST_TYPE).asType()); - mMultipartRequest = TypeName.get(mElements.getTypeElement(Constants.MULTIPART_REQUEST_TYPE).asType()); - mResponse = TypeName.get(mElements.getTypeElement(Constants.RESPONSE_TYPE).asType()); - mHttpMethod = TypeName.get(mElements.getTypeElement(Constants.HTTP_METHOD_TYPE).asType()); - mHttpHeaders = TypeName.get(mElements.getTypeElement(Constants.HTTP_HEADERS_TYPE).asType()); - mSession = TypeName.get(mElements.getTypeElement(Constants.SESSION_TYPE).asType()); - mRequestBody = TypeName.get(mElements.getTypeElement(Constants.REQUEST_BODY_TYPE).asType()); - mMultipartFile = TypeName.get(mElements.getTypeElement(Constants.MULTIPART_FILE_TYPE).asType()); - mMultipartFileArray = ArrayTypeName.of(mMultipartFile); - mMultipartFileList = ParameterizedTypeName.get(ClassName.get(List.class), mMultipartFile); - - mAddition = TypeName.get(mElements.getTypeElement(Constants.ADDITION_TYPE).asType()); - mCrossOrigin = TypeName.get(mElements.getTypeElement(Constants.CROSS_ORIGIN_TYPE).asType()); - mMapping = TypeName.get(mElements.getTypeElement(Constants.MAPPING_TYPE).asType()); - mMimeTypeMapping = TypeName.get(mElements.getTypeElement(Constants.MIME_MAPPING_TYPE).asType()); - mMethodMapping = TypeName.get(mElements.getTypeElement(Constants.METHOD_MAPPING_TYPE).asType()); - mPairMapping = TypeName.get(mElements.getTypeElement(Constants.PAIR_MAPPING_TYPE).asType()); - mPathMapping = TypeName.get(mElements.getTypeElement(Constants.PATH_MAPPING_TYPE).asType()); - mMappingList = ParameterizedTypeName.get(ClassName.get(Map.class), mMapping, mHandler); - } - - @Override - public boolean process(Set set, RoundEnvironment roundEnv) { - if (CollectionUtils.isEmpty(set)) { - return false; - } - - Set appSet = roundEnv.getElementsAnnotatedWith(AppInfo.class); - String registerPackageName = getRegisterPackageName(appSet); - - Map> controllers = new HashMap<>(); - findMapping(roundEnv.getElementsAnnotatedWith(RequestMapping.class), controllers); - findMapping(roundEnv.getElementsAnnotatedWith(GetMapping.class), controllers); - findMapping(roundEnv.getElementsAnnotatedWith(PostMapping.class), controllers); - findMapping(roundEnv.getElementsAnnotatedWith(PutMapping.class), controllers); - findMapping(roundEnv.getElementsAnnotatedWith(PatchMapping.class), controllers); - findMapping(roundEnv.getElementsAnnotatedWith(DeleteMapping.class), controllers); - - if (!controllers.isEmpty()) { - createHandlerAdapter(registerPackageName, controllers); - } - return true; - } - - private void findMapping(Set set, Map> controllerMap) { - for (Element element: set) { - if (element instanceof ExecutableElement) { - ExecutableElement execute = (ExecutableElement) element; - Element enclosing = element.getEnclosingElement(); - if (!(enclosing instanceof TypeElement)) { - continue; - } - - TypeElement type = (TypeElement) enclosing; - Annotation restController = type.getAnnotation(RestController.class); - Annotation controller = type.getAnnotation(Controller.class); - if (restController == null && controller == null) { - continue; - } - - String host = type.getQualifiedName() + "#" + execute.getSimpleName() + "()"; - - Set modifiers = execute.getModifiers(); - Validate.isTrue(!modifiers.contains(Modifier.PRIVATE), "The modifier private is redundant on %s.", - host); - - if (modifiers.contains(Modifier.STATIC)) { - - } - - List elementList = controllerMap.get(type); - if (CollectionUtils.isEmpty(elementList)) { - elementList = new ArrayList<>(); - controllerMap.put(type, elementList); - } - elementList.add(execute); - } - } - } - - private void createHandlerAdapter(String registerPackageName, - Map> controllers) { - Map> adapterMap = new HashMap<>(); - for (Map.Entry> entry: controllers.entrySet()) { - TypeElement type = entry.getKey(); - List executes = entry.getValue(); - mLog.i(String.format("------ Processing %s ------", type.getSimpleName())); - - String typeName = type.getQualifiedName().toString(); - Mapping typeMapping = getTypeMapping(type); - validateMapping(typeMapping, typeName); - - CrossOrigin typeCrossOrigin = type.getAnnotation(CrossOrigin.class); - - TypeName controllerType = TypeName.get(type.asType()); - FieldSpec hostField = FieldSpec.builder(controllerType, "mHost", Modifier.PRIVATE).build(); - FieldSpec mappingField = FieldSpec.builder(mMappingList, "mMappingMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder() - .addStatement("this.mHost = new $T()", type) - .addStatement("this.mMappingMap = new $T<>()", LinkedHashMap.class); - for (ExecutableElement execute: executes) { - Mapping mapping = getExecuteMapping(execute); - validateExecuteMapping(mapping, typeName + "#" + execute.getSimpleName().toString() + "()"); - - mapping = new Merge(typeMapping, mapping); - rootCode.beginControlFlow("\n").addStatement("$T mapping = new $T()", mMapping, mMapping); - addMapping(rootCode, mapping); - - Addition addition = execute.getAnnotation(Addition.class); - rootCode.add("\n").addStatement("$T addition = new $T()", mAddition, mAddition); - addAddition(rootCode, addition); - - CrossOrigin executeCrossOrigin = execute.getAnnotation(CrossOrigin.class); - if (typeCrossOrigin == null && executeCrossOrigin == null) { - rootCode.add("\n").addStatement("$T crossOrigin = null", mCrossOrigin); - } else { - rootCode.add("\n").addStatement("$T crossOrigin = new $T()", mCrossOrigin, mCrossOrigin); - MergeCrossOrigin crossOrigin = new MergeCrossOrigin(new CrossOriginImpl(typeCrossOrigin), - new CrossOriginImpl(executeCrossOrigin)); - addCrossOrigin(rootCode, crossOrigin); - } - - String handlerName = createHandler(type, execute, mapping.path(), mapping.isRest()); - rootCode.addStatement("$L handler = new $L(mHost, mapping, addition, crossOrigin)", handlerName, - handlerName).addStatement("mMappingMap.put(mapping, handler)").endControlFlow(); - } - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - MethodSpec mappingMethod = MethodSpec.methodBuilder("getMappingMap") - .addAnnotation(Override.class) - .addModifiers(Modifier.PROTECTED) - .returns(mMappingList) - .addStatement("return mMappingMap") - .build(); - - MethodSpec hostMethod = MethodSpec.methodBuilder("getHost") - .addAnnotation(Override.class) - .addModifiers(Modifier.PROTECTED) - .returns(controllerType) - .addStatement("return mHost") - .build(); - - String adapterPackageName = getPackageName(type).getQualifiedName().toString(); - String className = String.format("%sAdapter", type.getSimpleName()); - TypeSpec adapterClass = TypeSpec.classBuilder(className) - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .superclass(mMappingAdapter) - .addField(hostField) - .addField(mappingField) - .addMethod(rootMethod) - .addMethod(mappingMethod) - .addMethod(hostMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(adapterPackageName, adapterClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - - String group = getGroup(type); - List adapterList = adapterMap.get(group); - if (CollectionUtils.isEmpty(adapterList)) { - adapterList = new ArrayList<>(); - adapterMap.put(group, adapterList); - } - adapterList.add(adapterPackageName + "." + className); - } - - if (!adapterMap.isEmpty()) { - createRegister(registerPackageName, adapterMap); - } - } - - private Mapping getTypeMapping(TypeElement type) { - Mapping mapping = null; - boolean isRest = type.getAnnotation(ResponseBody.class) != null - || type.getAnnotation(RestController.class) != null; - RequestMapping requestMapping = type.getAnnotation(RequestMapping.class); - if (requestMapping != null) { - mapping = new Any(requestMapping, isRest); - } - - if (mapping == null) { - GetMapping getMapping = type.getAnnotation(GetMapping.class); - if (getMapping != null) { - mapping = new Get(getMapping, isRest); - } - } - if (mapping == null) { - PostMapping postMapping = type.getAnnotation(PostMapping.class); - if (postMapping != null) { - mapping = new Post(postMapping, isRest); - } - } - if (mapping == null) { - PutMapping putMapping = type.getAnnotation(PutMapping.class); - if (putMapping != null) { - mapping = new Put(putMapping, isRest); - } - } - if (mapping == null) { - PatchMapping patchMapping = type.getAnnotation(PatchMapping.class); - if (patchMapping != null) { - mapping = new Patch(patchMapping, isRest); - } - } - if (mapping == null) { - DeleteMapping deleteMapping = type.getAnnotation(DeleteMapping.class); - if (deleteMapping != null) { - mapping = new Delete(deleteMapping, isRest); - } - } - if (mapping == null) { - mapping = new Null(isRest); - } - return mapping; - } - - private void validateMapping(Mapping mapping, String host) { - String[] paths = mapping.path(); - if (ArrayUtils.isEmpty(paths)) { - paths = mapping.value(); - } - if (ArrayUtils.isNotEmpty(paths)) { - for (String path: paths) { - boolean valid = path.matches(PATH_STRICT) || path.matches(PATH_BLURRED_MAYBE); - Validate.isTrue(valid, "The format of path [%s] is wrong on %s.", path, host); - } - } - - String[] params = mapping.params(); - if (ArrayUtils.isNotEmpty(params)) { - for (String param: params) { - boolean valid = param.matches(PAIR_KEY); - valid = valid || param.matches(PAIR_KEY_VALUE); - valid = valid || param.matches(PAIR_NO_KEY); - valid = valid || param.matches(PAIR_NO_VALUE); - Validate.isTrue(valid, "The format of param [%s] is wrong on %s.", param, host); - } - } - - String[] headers = mapping.headers(); - if (ArrayUtils.isNotEmpty(headers)) { - for (String head: headers) { - boolean valid = head.matches(PAIR_KEY); - valid = valid || head.matches(PAIR_KEY_VALUE); - valid = valid || head.matches(PAIR_NO_KEY); - valid = valid || head.matches(PAIR_NO_VALUE); - Validate.isTrue(valid, "The format of header [%s] is wrong on %s.", head, host); - } - } - - String[] consumes = mapping.consumes(); - if (ArrayUtils.isNotEmpty(consumes)) { - for (String consume: consumes) { - try { - new MimeType(consume); - } catch (MimeTypeParseException e) { - throw new IllegalArgumentException( - String.format("The format of consume [%s] is wrong on %s.", consume, host)); - } - } - } - - String[] produces = mapping.produces(); - if (ArrayUtils.isNotEmpty(produces)) { - for (String produce: produces) { - try { - new MimeType(produce); - } catch (MimeTypeParseException e) { - throw new IllegalArgumentException( - String.format("The format of produce [%s] is wrong on %s.", produce, host)); - } - } - } - } - - private Mapping getExecuteMapping(ExecutableElement execute) { - Mapping mapping = null; - RequestMapping requestMapping = execute.getAnnotation(RequestMapping.class); - boolean isRest = execute.getAnnotation(ResponseBody.class) != null; - if (requestMapping != null) { - mapping = new Any(requestMapping, isRest); - } - - if (mapping == null) { - GetMapping getMapping = execute.getAnnotation(GetMapping.class); - if (getMapping != null) { - mapping = new Get(getMapping, isRest); - } - } - if (mapping == null) { - PostMapping postMapping = execute.getAnnotation(PostMapping.class); - if (postMapping != null) { - mapping = new Post(postMapping, isRest); - } - } - if (mapping == null) { - PutMapping putMapping = execute.getAnnotation(PutMapping.class); - if (putMapping != null) { - mapping = new Put(putMapping, isRest); - } - } - if (mapping == null) { - PatchMapping patchMapping = execute.getAnnotation(PatchMapping.class); - if (patchMapping != null) { - mapping = new Patch(patchMapping, isRest); - } - } - if (mapping == null) { - DeleteMapping deleteMapping = execute.getAnnotation(DeleteMapping.class); - if (deleteMapping != null) { - mapping = new Delete(deleteMapping, isRest); - } - } - return mapping; - } - - private void validateExecuteMapping(Mapping mapping, String host) { - String[] paths = mapping.path(); - if (ArrayUtils.isEmpty(paths)) { - paths = mapping.value(); - } - Validate.notEmpty(paths, String.format("The path value of method cannot be empty on %s.", host)); - validateMapping(mapping, host); - } - - private void addMapping(CodeBlock.Builder builder, Mapping mapping) { - String[] pathArray = mapping.path(); - builder.add("\n").addStatement("$T path = new $T()", mPathMapping, mPathMapping); - for (String path: pathArray) { - builder.addStatement("path.addRule($S)", path); - } - builder.addStatement("mapping.setPath(path)"); - - String[] methodArray = mapping.method(); - builder.add("\n").addStatement("$T method = new $T()", mMethodMapping, mMethodMapping); - for (String method: methodArray) { - builder.addStatement("method.addRule($S)", method); - } - builder.addStatement("mapping.setMethod(method)"); - - String[] paramArray = mapping.params(); - if (ArrayUtils.isNotEmpty(paramArray)) { - builder.add("\n").addStatement("$T param = new $T()", mPairMapping, mPairMapping); - for (String param: paramArray) { - builder.addStatement("param.addRule($S)", param); - } - builder.addStatement("mapping.setParam(param)"); - } - - String[] headerArray = mapping.headers(); - if (ArrayUtils.isNotEmpty(headerArray)) { - builder.add("\n").addStatement("$T header = new $T()", mPairMapping, mPairMapping); - for (String header: headerArray) { - builder.addStatement("header.addRule($S)", header); - } - builder.addStatement("mapping.setHeader(header)"); - } - - String[] consumeArray = mapping.consumes(); - if (ArrayUtils.isNotEmpty(consumeArray)) { - builder.add("\n").addStatement("$T consume = new $T()", mMimeTypeMapping, mMimeTypeMapping); - for (String consume: consumeArray) { - builder.addStatement("consume.addRule($S)", consume); - } - builder.addStatement("mapping.setConsume(consume)"); - } - - String[] produceArray = mapping.produces(); - if (ArrayUtils.isNotEmpty(produceArray)) { - builder.add("\n").addStatement("$T produce = new $T()", mMimeTypeMapping, mMimeTypeMapping); - for (String produce: produceArray) { - builder.addStatement("produce.addRule($S)", produce); - } - builder.addStatement("mapping.setProduce(produce)"); - } - } - - private void addAddition(CodeBlock.Builder builder, Addition addition) { - if (addition == null) { - return; - } - - String[] stringType = addition.stringType(); - if (ArrayUtils.isEmpty(stringType)) { - stringType = addition.value(); - } - StringBuilder stringArray = new StringBuilder(); - for (String type: stringType) { - if (stringArray.length() > 0) { - stringArray.append(", "); - } - stringArray.append("\"").append(type).append("\""); - } - builder.add("\n") - .addStatement("String[] stringType = new String[]{$L}", stringArray) - .addStatement("addition.setStringType(stringType)"); - - boolean[] booleanType = addition.booleanType(); - StringBuilder booleanArray = new StringBuilder(); - for (boolean type: booleanType) { - if (booleanArray.length() > 0) { - booleanArray.append(", "); - } - booleanArray.append(type); - } - builder.add("\n") - .addStatement("boolean[] booleanType = new boolean[]{$L}", booleanArray) - .addStatement("addition.setBooleanType(booleanType)"); - - int[] intType = addition.intTypeType(); - StringBuilder intArray = new StringBuilder(); - for (int type: intType) { - if (intArray.length() > 0) { - intArray.append(", "); - } - intArray.append(type); - } - builder.add("\n") - .addStatement("int[] intType = new int[]{$L}", intArray) - .addStatement("addition.setIntType(intType)"); - - long[] longType = addition.longType(); - StringBuilder longArray = new StringBuilder(); - for (long type: longType) { - if (longArray.length() > 0) { - longArray.append(", "); - } - longArray.append(type).append("L"); - } - builder.add("\n") - .addStatement("long[] longType = new long[]{$L}", longArray) - .addStatement("addition.setLongType(longType)"); - - short[] shortType = addition.shortType(); - StringBuilder shortArray = new StringBuilder(); - for (short type: shortType) { - if (shortArray.length() > 0) { - shortArray.append(", "); - } - shortArray.append(type); - } - builder.add("\n") - .addStatement("short[] shortType = new short[]{$L}", shortArray) - .addStatement("addition.setShortType(shortType)"); - - float[] floatType = addition.floatType(); - StringBuilder floatArray = new StringBuilder(); - for (float type: floatType) { - if (floatArray.length() > 0) { - floatArray.append(", "); - } - floatArray.append(type).append("F"); - } - builder.add("\n") - .addStatement("float[] floatType = new float[]{$L}", floatArray) - .addStatement("addition.setFloatType(floatType)"); - - double[] doubleType = addition.doubleType(); - StringBuilder doubleArray = new StringBuilder(); - for (double type: doubleType) { - if (doubleArray.length() > 0) { - doubleArray.append(", "); - } - doubleArray.append(type).append("D"); - } - builder.add("\n") - .addStatement("double[] doubleType = new double[]{$L}", doubleArray) - .addStatement("addition.setDoubleType(doubleType)"); - - byte[] byteType = addition.byteType(); - StringBuilder byteArray = new StringBuilder(); - for (byte type: byteType) { - if (byteArray.length() > 0) { - byteArray.append(", "); - } - byteArray.append(type); - } - builder.add("\n") - .addStatement("byte[] byteType = new byte[]{$L}", byteArray) - .addStatement("addition.setByteType(byteType)"); - - char[] charType = addition.charType(); - StringBuilder charArray = new StringBuilder(); - for (char type: charType) { - if (charArray.length() > 0) { - charArray.append(", "); - } - charArray.append("'").append(type).append("'"); - } - builder.add("\n") - .addStatement("char[] charType = new char[]{$L}", charArray) - .addStatement("addition.setCharType(charType)"); - } - - private void addCrossOrigin(CodeBlock.Builder builder, MergeCrossOrigin crossOrigin) { - String[] origins = crossOrigin.origins(); - StringBuilder originsArray = new StringBuilder(); - for (String origin: origins) { - if (originsArray.length() > 0) { - originsArray.append(", "); - } - originsArray.append("\"").append(origin).append("\""); - } - builder.add("\n") - .addStatement("String[] origins = new String[]{$L}", originsArray) - .addStatement("crossOrigin.setOrigins(origins)"); - - String[] allowedHeaders = crossOrigin.allowedHeaders(); - StringBuilder allowedHeadersArray = new StringBuilder(); - for (String header: allowedHeaders) { - if (allowedHeadersArray.length() > 0) { - allowedHeadersArray.append(", "); - } - allowedHeadersArray.append("\"").append(header).append("\""); - } - builder.add("\n") - .addStatement("String[] allowedHeaders = new String[]{$L}", allowedHeadersArray) - .addStatement("crossOrigin.setAllowedHeaders(allowedHeaders)"); - - String[] exposedHeaders = crossOrigin.exposedHeaders(); - StringBuilder exposedHeadersArray = new StringBuilder(); - for (String header: exposedHeaders) { - if (exposedHeadersArray.length() > 0) { - exposedHeadersArray.append(", "); - } - exposedHeadersArray.append("\"").append(header).append("\""); - } - builder.add("\n") - .addStatement("String[] exposedHeaders = new String[]{$L}", exposedHeadersArray) - .addStatement("crossOrigin.setExposedHeaders(exposedHeaders)"); - - String[] methods = crossOrigin.methods(); - StringBuilder methodsArray = new StringBuilder(); - for (String method: methods) { - if (methodsArray.length() > 0) { - methodsArray.append(", "); - } - methodsArray.append("HttpMethod.").append(method); - } - builder.add("\n") - .addStatement("$T[] methods = new $T[]{$L}", mHttpMethod, mHttpMethod, methodsArray) - .addStatement("crossOrigin.setMethods(methods)"); - - boolean allowCredentials = crossOrigin.allowCredentials(); - builder.add("\n").addStatement("crossOrigin.setAllowCredentials($L)", allowCredentials); - - long maxAge = crossOrigin.maxAge(); - builder.addStatement("crossOrigin.setMaxAge($L)", maxAge); - } - - /** - * Create a handler class and return the simple name of the handler. - * - * @return the simple name, such as the simple name of the class {@code com.example.User} is {@code User}. - */ - private String createHandler(TypeElement type, ExecutableElement execute, String[] paths, boolean isRest) { - FieldSpec hostField = FieldSpec.builder(Object.class, "mHost").addModifiers(Modifier.PRIVATE).build(); - - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addParameter(Object.class, "host") - .addParameter(mMapping, "mapping") - .addParameter(mAddition, "addition") - .addParameter(mCrossOrigin, "crossOrigin") - .addStatement("super(host, mapping, addition, crossOrigin)") - .addStatement("this.mHost = host") - .build(); - - CodeBlock.Builder handleCode = CodeBlock.builder() - .addStatement("$T context = ($T)request.getAttribute($T.ANDROID_CONTEXT)", mContext, mContext, mRequest) - .addStatement("String httpPath = request.getPath()") - .addStatement("$T httpMethod = request.getMethod()", mHttpMethod) - .add("\n") - .addStatement("Object converterObj = request.getAttribute($T.HTTP_MESSAGE_CONVERTER)", mRequest) - .addStatement("$T converter = null", mConverter) - .beginControlFlow("if (converterObj != null && converterObj instanceof $T)", mConverter) - .addStatement("converter = ($T)converterObj", mConverter) - .endControlFlow() - .add("\n") - .addStatement("$T multiRequest = null", mMultipartRequest) - .beginControlFlow("if (request instanceof $T)", mMultipartRequest) - .addStatement("multiRequest = ($T) request", mMultipartRequest) - .endControlFlow() - .add("\n") - .addStatement("$T requestBody = null", mRequestBody) - .beginControlFlow("if (httpMethod.allowBody())") - .addStatement("requestBody = request.getBody()") - .endControlFlow() - .add("\n") - .addStatement("$T pathMap = getPathVariable(httpPath)", Map.class) - .add("\n") - .add("/** ---------- Building Parameters ---------- **/ ") - .add("\n"); - - String host = type.getQualifiedName().toString() + "#" + execute.getSimpleName().toString() + "()"; - StringBuilder paramBuild = new StringBuilder(); - List parameters = execute.getParameters(); - if (!parameters.isEmpty()) { - for (int i = 0; i < parameters.size(); i++) { - VariableElement parameter = parameters.get(i); - - TypeName typeName = TypeName.get(parameter.asType()); - if (mContext.equals(typeName)) { - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append("context"); - continue; - } - - if (mRequest.equals(typeName)) { - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append("request"); - continue; - } - - if (mResponse.equals(typeName)) { - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append("response"); - continue; - } - - if (mSession.equals(typeName)) { - handleCode.add("\n").addStatement("$T session$L = request.getValidSession()", mSession, i); - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format("session%s", i)); - continue; - } - - if (mRequestBody.equals(typeName)) { - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append("requestBody"); - continue; - } - - RequestHeader requestHeader = parameter.getAnnotation(RequestHeader.class); - if (requestHeader != null) { - Validate.isTrue(isBasicType(typeName), - "The RequestHeader annotation only supports [String, int, long, float, double, boolean] on %s.", - host); - - String name = requestHeader.name(); - if (StringUtils.isEmpty(name)) { - name = requestHeader.value(); - } - Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host); - - handleCode.add("\n").addStatement("String header$LStr = request.getHeader($S)", i, name); - if (requestHeader.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(header$LStr))", mTextUtils, i) - .addStatement("throw new $T($S)", mHeaderMissing, name) - .endControlFlow(); - } else { - handleCode.beginControlFlow("if ($T.isEmpty(header$LStr))", mTextUtils, i) - .addStatement("header$LStr = $S", i, requestHeader.defaultValue()) - .endControlFlow(); - } - - createBasicParameter(handleCode, typeName, "header", i); - assignmentBasicParameter(handleCode, typeName, "header", i); - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "header%d", i)); - continue; - } - - CookieValue cookieValue = parameter.getAnnotation(CookieValue.class); - if (cookieValue != null) { - Validate.isTrue(mString.equals(typeName), - "CookieValue can only be used with [String] on %s.", host); - - String name = cookieValue.name(); - if (StringUtils.isEmpty(name)) { - name = cookieValue.value(); - } - Validate.notEmpty(name, "The name of cookie is null on %s.", host); - - handleCode.add("\n").addStatement("String cookie$L = request.getCookieValue($S)", i, name); - if (cookieValue.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(cookie$L))", mTextUtils, i) - .addStatement("throw new $T($S)", mCookieMissing, name) - .endControlFlow(); - } - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "cookie%d", i)); - continue; - } - - PathVariable pathVariable = parameter.getAnnotation(PathVariable.class); - if (pathVariable != null) { - Validate.isTrue(isBasicType(typeName), "The PathVariable annotation only supports " + - "[String, int, long, float, double, boolean] on %s.", host); - - String name = pathVariable.name(); - if (StringUtils.isEmpty(name)) { - name = pathVariable.value(); - } - Validate.isTrue(!StringUtils.isEmpty(name), "The name of path is null on %s.", host); - - boolean isBlurred = false; - for (String path: paths) { - if (path.matches(PATH_BLURRED_MAYBE) && mBlurredPathPattern.matcher(path).find()) { - isBlurred = true; - } - } - Validate.isTrue(isBlurred, "The PathVariable annotation must have a blurred path, " + - "for example [/project/{name}]. The error occurred on %s.", host); - - handleCode.add("\n").addStatement("String path$LStr = pathMap.get($S)", i, name); - - if (pathVariable.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(path$LStr))", mTextUtils, i) - .addStatement("throw new $T($S)", mPathMissing, name) - .endControlFlow(); - } else { - handleCode.beginControlFlow("if ($T.isEmpty(path$LStr))", mTextUtils, i) - .addStatement("path$LStr = $S;", i, pathVariable.defaultValue()) - .endControlFlow(); - } - - createBasicParameter(handleCode, typeName, "path", i); - assignmentBasicParameter(handleCode, typeName, "path", i); - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "path%d", i)); - continue; - } - - QueryParam queryParam = parameter.getAnnotation(QueryParam.class); - if (queryParam != null) { - boolean isBasicType = isBasicType(typeName); - boolean isBasicArrayType = isBasicArrayType(typeName); - Validate.isTrue(isBasicType || isBasicArrayType, "The QueryParam annotation " + - "only supports [String, int, long, float, double, boolean] on %s.", host); - - String name = queryParam.name(); - if (StringUtils.isEmpty(name)) { - name = queryParam.value(); - } - Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host); - - if (isBasicType) { - handleCode.add("\n").addStatement("String param$LStr = request.getQuery($S)", i, name); - if (queryParam.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } else { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("param$LStr = $S", i, queryParam.defaultValue()) - .endControlFlow(); - } - - createBasicParameter(handleCode, typeName, "param", i); - assignmentBasicParameter(handleCode, typeName, "param", i); - } else { - handleCode.add("\n") - .addStatement("$T param$LList = request.getQueries($S)", mStringList, i, name); - if (queryParam.required()) { - handleCode.beginControlFlow("if (param$LList == null || param$LList.isEmpty())", i, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } else { - String defaultValue = queryParam.defaultValue(); - if (StringUtils.isNotEmpty(defaultValue)) { - handleCode.beginControlFlow("if (param$LList = null || param$LList.isEmpty())", i, i) - .addStatement("param$LList = new $T<>()", i, TypeName.get(ArrayList.class)) - .addStatement("param$LList.add($S)", i, defaultValue) - .endControlFlow(); - } - } - - createBasicArrayParameter(handleCode, typeName, i); - assignmentBasicArrayParameter(handleCode, typeName, i); - } - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "param%d", i)); - continue; - } - - RequestParam requestParam = parameter.getAnnotation(RequestParam.class); - if (requestParam != null) { - boolean isFile = mMultipartFile.equals(typeName) || mMultipartFileArray.equals(typeName); - boolean isBasicType = isBasicType(typeName); - boolean isBasicArrayType = isBasicArrayType(typeName); - - String name = requestParam.name(); - if (StringUtils.isEmpty(name)) { - name = requestParam.value(); - } - Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host); - - handleCode.add("\n"); - if (isFile) { - if (mMultipartFile.equals(typeName)) { - handleCode.addStatement("$T param$L = null", mMultipartFile, i) - .beginControlFlow("if (multiRequest != null)") - .addStatement("param$L = multiRequest.getFile($S)", i, name) - .endControlFlow(); - if (requestParam.required()) { - handleCode.beginControlFlow("if (param$L == null)", i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } - } else { - handleCode.addStatement("$T param$LList = null", mMultipartFileList, i) - .beginControlFlow("if (multiRequest != null)") - .addStatement("param$LList = multiRequest.getFiles($S)", i, name) - .endControlFlow(); - if (requestParam.required()) { - handleCode.beginControlFlow("if (param$LList == null || param$LList.isEmpty())", i, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } - - handleCode.addStatement("int param$LListSize = param$LList.size()", i, i) - .addStatement("$T[] param$L = new $T[param$LListSize]", mMultipartFile, i, - mMultipartFile, - i) - .beginControlFlow("if(param$LListSize > 0)", i) - .addStatement("param$LList.toArray(param$L)", i, i) - .endControlFlow(); - } - } else if (isBasicType) { - handleCode.addStatement("String param$LStr = request.getParameter($S)", i, name); - - if (requestParam.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } else { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("param$LStr = $S", i, requestParam.defaultValue()) - .endControlFlow(); - } - - createBasicParameter(handleCode, typeName, "param", i); - assignmentBasicParameter(handleCode, typeName, "param", i); - } else if (isBasicArrayType) { - handleCode.addStatement("$T param$LList = request.getParameters($S)", mStringList, i, name); - if (requestParam.required()) { - handleCode.beginControlFlow("if (param$LList == null || param$LList.isEmpty())", i, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } else { - String defaultValue = requestParam.defaultValue(); - if (StringUtils.isNotEmpty(defaultValue)) { - handleCode.beginControlFlow("if (param$LList == null || param$LList.isEmpty())", i, i) - .addStatement("param$LList = new $T<>()", i, TypeName.get(ArrayList.class)) - .addStatement("param$LList.add($S)", i, defaultValue) - .endControlFlow(); - } - } - - createBasicArrayParameter(handleCode, typeName, i); - assignmentBasicArrayParameter(handleCode, typeName, i); - } else { - handleCode.addStatement("String param$LStr = request.getParameter($S)", i, name); - - if (requestParam.required()) { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } else { - handleCode.beginControlFlow("if ($T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("param$LStr = $S", i, requestParam.defaultValue()) - .endControlFlow(); - } - - TypeName wrapperType = ParameterizedTypeName.get(mTypeWrapper, typeName); - handleCode.addStatement("$T param$L = null", typeName, i) - .beginControlFlow("if (converter != null && !$T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("byte[] data = param$LStr.getBytes()", i) - .addStatement("$T stream = new $T(data)", InputStream.class, ByteArrayInputStream.class) - .addStatement("$T mimeType = $T.TEXT_PLAIN", mMediaType, mMediaType) - .addStatement("$T type = new $T(){}.getType()", Type.class, wrapperType) - .addStatement("param$L = converter.convert(stream, mimeType, type)", i) - .endControlFlow(); - } - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "param%d", i)); - continue; - } - - FormPart formPart = parameter.getAnnotation(FormPart.class); - if (formPart != null) { - String name = formPart.name(); - if (StringUtils.isEmpty(name)) { - name = formPart.value(); - } - Validate.isTrue(!StringUtils.isEmpty(name), "The name of param is null on %s.", host); - - handleCode.add("\n"); - if (mMultipartFile.equals(typeName)) { - handleCode.addStatement("$T param$L = null", mMultipartFile, i) - .beginControlFlow("if (multiRequest != null)") - .addStatement("param$L = multiRequest.getFile($S)", i, name) - .endControlFlow(); - if (formPart.required()) { - handleCode.beginControlFlow("if (param$L == null)", i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } - } else if (mMultipartFileArray.equals(typeName)) { - handleCode.addStatement("$T param$LList = null", mMultipartFileList, i) - .beginControlFlow("if (multiRequest != null)") - .addStatement("param$LList = multiRequest.getFiles($S)", i, name) - .endControlFlow(); - if (formPart.required()) { - handleCode.beginControlFlow("if (param$LList == null || param$LList.isEmpty())", i, i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } - - handleCode.addStatement("int param$LListSize = param$LList.size()", i, i) - .addStatement("$T[] param$L = new $T[param$LListSize]", - mMultipartFile, i, mMultipartFile, i) - .beginControlFlow("if(param$LListSize > 0)", i) - .addStatement("param$LList.toArray(param$L)", i, i) - .endControlFlow(); - } else { - TypeName wrapperType = ParameterizedTypeName.get(mTypeWrapper, typeName); - handleCode.addStatement("$T param$L = null", typeName, i) - .beginControlFlow("if (converter != null && multiRequest != null)") - .addStatement("$T param$LType = new $T(){}.getType()", Type.class, i, wrapperType) - .addStatement("$T param$LFile = multiRequest.getFile($S)", mMultipartFile, i, name) - .beginControlFlow("if (param$LFile != null)", i) - .addStatement("$T stream = param$LFile.getStream()", InputStream.class, i) - .addStatement("$T mimeType = param$LFile.getContentType()", mMediaType, i) - .addStatement("param$L = converter.convert(stream, mimeType, param$LType)", i, i) - .endControlFlow() - .beginControlFlow("if (param$L == null)", i) - .addStatement("String param$LStr = multiRequest.getParameter($S)", i, name) - .beginControlFlow("if (!$T.isEmpty(param$LStr))", mTextUtils, i) - .addStatement("byte[] data = param$LStr.getBytes()", i) - .addStatement("$T stream = new $T(data)", InputStream.class, ByteArrayInputStream.class) - .addStatement("$T mimeType = $T.TEXT_PLAIN", mMediaType, mMediaType) - .addStatement("param$L = converter.convert(stream, mimeType, param$LType)", i, i) - .endControlFlow() - .endControlFlow() - .endControlFlow(); - - if (formPart.required()) { - handleCode.beginControlFlow("if (param$L == null)", i) - .addStatement("throw new $T($S)", mParamMissing, name) - .endControlFlow(); - } - } - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "param%d", i)); - continue; - } - - RequestBody requestBody = parameter.getAnnotation(RequestBody.class); - if (requestBody != null) { - handleCode.add("\n"); - - if (mString.equals(typeName)) { - handleCode.addStatement("String body$L = requestBody.string()", i); - } else { - TypeName wrapperType = ParameterizedTypeName.get(mTypeWrapper, typeName); - handleCode.addStatement("$T body$L = null", typeName, i) - .beginControlFlow("if (converter != null && requestBody != null)") - .addStatement("$T body$LType = new $T(){}.getType()", Type.class, i, wrapperType) - .addStatement("$T stream = requestBody.stream()", InputStream.class) - .addStatement("$T mimeType = requestBody.contentType()", mMediaType) - .addStatement("body$L = converter.convert(stream, mimeType, body$LType)", i, i) - .endControlFlow(); - } - - if (requestBody.required()) { - handleCode.beginControlFlow("if (body$L == null)", i) - .addStatement("throw new $T()", mBodyMissing) - .endControlFlow(); - } - - if (paramBuild.length() > 0) { - paramBuild.append(", "); - } - paramBuild.append(String.format(Locale.getDefault(), "body%d", i)); - continue; - } - - throw new IllegalStateException( - String.format("The parameter type [%s] is not supported on %s.", typeName, host)); - } - } - - String executeName = execute.getSimpleName().toString(); - TypeMirror returnMirror = execute.getReturnType(); - boolean isVoid = TypeKind.VOID.equals(returnMirror.getKind()); - if (isVoid) { - handleCode.addStatement("(($T)mHost).$L($L)", type, executeName, paramBuild.toString()); - } else { - handleCode.addStatement("Object o = (($T)mHost).$L($L)", type, executeName, paramBuild.toString()); - } - handleCode.addStatement("return new $T($L, $L)", mViewObject, isRest, isVoid ? null : "o"); - - MethodSpec handleMethod = MethodSpec.methodBuilder("onHandle") - .addAnnotation(Override.class) - .addModifiers(Modifier.PROTECTED) - .returns(mView) - .addParameter(mRequest, "request") - .addParameter(mResponse, "response") - .addException(Throwable.class) - .addCode(handleCode.build()) - .build(); - - - String packageName = getPackageName(type).getQualifiedName().toString(); - executeName = StringUtils.capitalize(executeName); - String className = String.format("%s%sHandler%s", type.getSimpleName(), executeName, ""); - int i = 0; - while (mHashCodes.contains(className.hashCode())) { - i++; - className = String.format("%s%sHandler%s", type.getSimpleName(), executeName, i); - } - mHashCodes.add(className.hashCode()); - - TypeSpec handlerClass = TypeSpec.classBuilder(className) - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .superclass(mMappingHandler) - .addField(hostField) - .addMethod(rootMethod) - .addMethod(handleMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(packageName, handlerClass).build(); - try { - javaFile.writeTo(mFiler); - return className; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private boolean isBasicType(TypeName typeName) { - return mString.equals(typeName) || TypeName.INT.equals(typeName) || TypeName.LONG.equals(typeName) || - TypeName.FLOAT.equals(typeName) || TypeName.DOUBLE.equals(typeName) || TypeName.BOOLEAN.equals(typeName); - } - - private void createBasicParameter(CodeBlock.Builder builder, TypeName type, String name, int index) { - TypeName box = type.isBoxedPrimitive() ? type : type.box(); - builder.addStatement("$T $L$L = null", box, name, index); - } - - private void assignmentBasicParameter(CodeBlock.Builder builder, TypeName type, String name, int index) { - builder.beginControlFlow("try"); - TypeName box = type.isBoxedPrimitive() ? type : type.box(); - builder.addStatement("$L$L = $T.valueOf($L$LStr)", name, index, box, name, index); - builder.nextControlFlow("catch (Throwable e)").addStatement("throw new $T(e)", mParamError).endControlFlow(); - } - - private boolean isBasicArrayType(TypeName typeName) { - return mStringArray.equals(typeName) || mIntArray.equals(typeName) || mLongArray.equals(typeName) || - mFloatArray.equals(typeName) || mDoubleArray.equals(typeName) || mBooleanArray.equals(typeName); - } - - private void createBasicArrayParameter(CodeBlock.Builder builder, TypeName type, int index) { - TypeName component = ((ArrayTypeName) type).componentType; - builder.addStatement("$T[] param$L = new $T[param$LList.size()]", component, index, component, index); - } - - private void assignmentBasicArrayParameter(CodeBlock.Builder builder, TypeName type, int index) { - builder.beginControlFlow("try"); - TypeName component = ((ArrayTypeName) type).componentType; - TypeName box = component.isBoxedPrimitive() ? component : component.box(); - builder.beginControlFlow("for(int i = 0; i < param$LList.size(); i++)", index) - .addStatement("param$L[i] = $T.valueOf(param$LList.get(i))", index, box, index) - .endControlFlow(); - builder.nextControlFlow("catch (Throwable e)").addStatement("throw new $T(e)", mParamError).endControlFlow(); - } - - private void createRegister(String packageName, Map> adapterMap) { - TypeName listTypeName = ParameterizedTypeName.get(ClassName.get(List.class), mAdapter); - TypeName typeName = ParameterizedTypeName.get(ClassName.get(Map.class), mString, listTypeName); - FieldSpec mapField = FieldSpec.builder(typeName, "mMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder().addStatement("this.mMap = new $T<>()", HashMap.class); - for (Map.Entry> entry: adapterMap.entrySet()) { - String group = entry.getKey(); - List adapterList = entry.getValue(); - - CodeBlock.Builder groupCode = CodeBlock.builder() - .addStatement("List<$T> $LList = new $T<>()", mAdapter, group, ArrayList.class); - for (String adapterName: adapterList) { - ClassName className = ClassName.bestGuess(adapterName); - groupCode.addStatement("$LList.add(new $T())", group, className); - } - - rootCode.add(groupCode.build()); - rootCode.addStatement("this.mMap.put($S, $LList)", group, group); - } - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - MethodSpec registerMethod = MethodSpec.methodBuilder("onRegister") - .addAnnotation(Override.class) - .addModifiers(Modifier.PUBLIC) - .addParameter(mContext, "context") - .addParameter(mString, "group") - .addParameter(mRegisterType, "register") - .addStatement("List<$T> list = mMap.get(group)", mAdapter) - .beginControlFlow("if(list == null)") - .addStatement("list = new $T<>()", ArrayList.class) - .endControlFlow() - .addStatement("List<$T> defaultList = mMap.get($S)", mAdapter, "default") - .beginControlFlow("if(defaultList != null && !defaultList.isEmpty())") - .addStatement("list.addAll(defaultList)") - .endControlFlow() - .beginControlFlow("if(list != null && !list.isEmpty())") - .beginControlFlow("for ($T adapter : list)", mAdapter) - .addStatement("register.addAdapter(adapter)") - .endControlFlow() - .endControlFlow() - .build(); - - String className = "AdapterRegister"; - TypeSpec handlerClass = TypeSpec.classBuilder(className) - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addSuperinterface(mOnRegisterType) - .addField(mapField) - .addMethod(rootMethod) - .addMethod(registerMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(packageName, handlerClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String getGroup(TypeElement type) { - Controller controller = type.getAnnotation(Controller.class); - if (controller != null) { - return controller.value(); - } - RestController restController = type.getAnnotation(RestController.class); - if (restController != null) { - return restController.value(); - } - throw new IllegalStateException(String.format("The type is not a Controller: %1$s.", type)); - } - - private PackageElement getPackageName(Element element) { - while (element.getKind() != ElementKind.PACKAGE) { - element = element.getEnclosingElement(); - } - return (PackageElement) element; - } - - @Override - protected void addAnnotation(Set> classSet) { - classSet.add(RequestMapping.class); - classSet.add(GetMapping.class); - classSet.add(PostMapping.class); - classSet.add(PutMapping.class); - classSet.add(PatchMapping.class); - classSet.add(DeleteMapping.class); - classSet.add(AppInfo.class); - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/ConverterProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/ConverterProcessor.java deleted file mode 100644 index 91808c7a96517832756e947d39fac32dd53bd978..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/ConverterProcessor.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.google.auto.service.AutoService; -import com.squareup.javapoet.*; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.annotation.Converter; -import com.yanzhenjie.andserver.processor.util.Constants; -import com.yanzhenjie.andserver.processor.util.Logger; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.Validate; - -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -//@AutoService(Processor.class) -//@SupportedSourceVersion(SourceVersion.RELEASE_8) -//@SupportedAnnotationTypes({"com.yanzhenjie.andserver.annotation.Converter","com.yanzhenjie.andserver.annotation.AppInfo"}) -public class ConverterProcessor extends BaseProcessor { - - private Filer mFiler; - private Elements mElements; - private Logger mLog; - - private TypeName mContext; - private TypeName mOnRegisterType; - private TypeName mRegisterType; - - private TypeName mConverter; - private TypeName mString; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - mFiler = processingEnv.getFiler(); - mElements = processingEnv.getElementUtils(); - mLog = new Logger(processingEnv.getMessager()); - - mContext = TypeName.get(mElements.getTypeElement(Constants.CONTEXT_TYPE).asType()); - mOnRegisterType = TypeName.get(mElements.getTypeElement(Constants.ON_REGISTER_TYPE).asType()); - mRegisterType = TypeName.get(mElements.getTypeElement(Constants.REGISTER_TYPE).asType()); - - mConverter = TypeName.get(mElements.getTypeElement(Constants.CONVERTER_TYPE).asType()); - - mString = TypeName.get(String.class); - } - - @Override - public boolean process(Set set, RoundEnvironment roundEnv) { - if (CollectionUtils.isEmpty(set)) { - return false; - } - - Set appSet = roundEnv.getElementsAnnotatedWith(AppInfo.class); - String registerPackageName = getRegisterPackageName(appSet); - - Map converterMap = findAnnotation(roundEnv); - if (!converterMap.isEmpty()) { - createRegister(registerPackageName, converterMap); - } - return true; - } - - private Map findAnnotation(RoundEnvironment roundEnv) { - Set set = roundEnv.getElementsAnnotatedWith(Converter.class); - Map converterMap = new HashMap<>(); - - for (Element element: set) { - if (element instanceof TypeElement) { - TypeElement typeElement = (TypeElement) element; - Set modifiers = typeElement.getModifiers(); - Validate.isTrue(modifiers.contains(Modifier.PUBLIC), "The modifier public is missing on %s.", - typeElement.getQualifiedName()); - - List interfaces = typeElement.getInterfaces(); - if (CollectionUtils.isEmpty(interfaces)) { - mLog.w(String.format( - "The annotation Converter must be used in a subclass of [MessageConverter] on %s.", - typeElement.getQualifiedName())); - continue; - } - for (TypeMirror typeMirror: interfaces) { - if (mConverter.equals(TypeName.get(typeMirror))) { - converterMap.put(getGroup(typeElement), typeElement); - break; - } else { - mLog.w(String.format( - "The annotation Converter must be used in a subclass of [MessageConverter] on %s.", - typeElement.getQualifiedName())); - } - } - } - } - return converterMap; - } - - private void createRegister(String registerPackageName, Map converterMap) { - TypeName typeName = ParameterizedTypeName.get(ClassName.get(Map.class), mString, mConverter); - FieldSpec mapField = FieldSpec.builder(typeName, "mMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder().addStatement("this.mMap = new $T<>()", HashMap.class); - for (Map.Entry entry: converterMap.entrySet()) { - String group = entry.getKey(); - TypeElement converter = entry.getValue(); - mLog.i(String.format("------ Processing %s ------", converter.getSimpleName())); - rootCode.addStatement("this.mMap.put($S, new $T())", group, converter); - } - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - MethodSpec registerMethod = MethodSpec.methodBuilder("onRegister") - .addAnnotation(Override.class) - .addModifiers(Modifier.PUBLIC) - .addParameter(mContext, "context") - .addParameter(mString, "group") - .addParameter(mRegisterType, "register") - .addStatement("$T converter = mMap.get(group)", mConverter) - .beginControlFlow("if(converter == null)") - .addStatement("converter = mMap.get($S)", "default") - .endControlFlow() - .beginControlFlow("if(converter != null)") - .addStatement("register.setConverter(converter)") - .endControlFlow() - .build(); - - TypeSpec adapterClass = TypeSpec.classBuilder("ConverterRegister") - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addSuperinterface(mOnRegisterType) - .addField(mapField) - .addMethod(rootMethod) - .addMethod(registerMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(registerPackageName, adapterClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String getGroup(TypeElement type) { - Converter converter = type.getAnnotation(Converter.class); - if (converter != null) { - return converter.value(); - } - throw new IllegalStateException(String.format("The type is not a Converter: %1$s.", type)); - } - - @Override - protected void addAnnotation(Set> classSet) { - classSet.add(Converter.class); - classSet.add(AppInfo.class); - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/InterceptorProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/InterceptorProcessor.java deleted file mode 100644 index b2aa0fb04b2d4091fdde522af44312849f8d733b..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/InterceptorProcessor.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.google.auto.service.AutoService; -import com.squareup.javapoet.*; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.annotation.Interceptor; -import com.yanzhenjie.andserver.processor.util.Constants; -import com.yanzhenjie.andserver.processor.util.Logger; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.Validate; - -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.*; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ - -//@AutoService(Processor.class) -//@SupportedSourceVersion(SourceVersion.RELEASE_8) -//@SupportedAnnotationTypes({"com.yanzhenjie.andserver.annotation.Interceptor","com.yanzhenjie.andserver.annotation.AppInfo"}) -public class InterceptorProcessor extends BaseProcessor { - - private Filer mFiler; - private Elements mElements; - private Logger mLog; - - private TypeName mContext; - private TypeName mOnRegisterType; - private TypeName mRegisterType; - - private TypeName mInterceptor; - - private TypeName mString; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - mFiler = processingEnv.getFiler(); - mElements = processingEnv.getElementUtils(); - mLog = new Logger(processingEnv.getMessager()); - - mContext = TypeName.get(mElements.getTypeElement(Constants.CONTEXT_TYPE).asType()); - mOnRegisterType = TypeName.get(mElements.getTypeElement(Constants.ON_REGISTER_TYPE).asType()); - mRegisterType = TypeName.get(mElements.getTypeElement(Constants.REGISTER_TYPE).asType()); - - mInterceptor = TypeName.get(mElements.getTypeElement(Constants.INTERCEPTOR_TYPE).asType()); - - mString = TypeName.get(String.class); - } - - @Override - public boolean process(Set set, RoundEnvironment roundEnv) { - if (CollectionUtils.isEmpty(set)) { - return false; - } - - Set appSet = roundEnv.getElementsAnnotatedWith(AppInfo.class); - String registerPackageName = getRegisterPackageName(appSet); - - Map> interceptorMap = findAnnotation(roundEnv); - if (!interceptorMap.isEmpty()) { - createRegister(registerPackageName, interceptorMap); - } - return true; - } - - private Map> findAnnotation(RoundEnvironment roundEnv) { - Set set = roundEnv.getElementsAnnotatedWith(Interceptor.class); - Map> interceptorMap = new HashMap<>(); - - for (Element element: set) { - if (element instanceof TypeElement) { - TypeElement typeElement = (TypeElement) element; - - Set modifiers = typeElement.getModifiers(); - Validate.isTrue(modifiers.contains(Modifier.PUBLIC), "The modifier public is missing on %s.", - typeElement.getQualifiedName()); - - List interfaces = typeElement.getInterfaces(); - if (CollectionUtils.isEmpty(interfaces)) { - mLog.w(String.format( - "The annotation Interceptor must be used in a subclass of [HandlerInterceptor] on %s.", - typeElement.getQualifiedName())); - continue; - } - for (TypeMirror typeMirror: interfaces) { - if (mInterceptor.equals(TypeName.get(typeMirror))) { - String group = getGroup(typeElement); - List elementList = interceptorMap.get(group); - if (CollectionUtils.isEmpty(elementList)) { - elementList = new ArrayList<>(); - interceptorMap.put(group, elementList); - } - elementList.add(typeElement); - break; - } else { - mLog.w(String.format( - "The annotation Interceptor must be used in a subclass of [HandlerInterceptor] on %s.", - typeElement.getQualifiedName())); - } - } - } - } - return interceptorMap; - } - - private void createRegister(String registerPackageName, Map> interceptorMap) { - TypeName listTypeName = ParameterizedTypeName.get(ClassName.get(List.class), mInterceptor); - TypeName typeName = ParameterizedTypeName.get(ClassName.get(Map.class), mString, listTypeName); - FieldSpec mapField = FieldSpec.builder(typeName, "mMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder().addStatement("this.mMap = new $T<>()", HashMap.class); - for (Map.Entry> entry: interceptorMap.entrySet()) { - String group = entry.getKey(); - List interceptorList = entry.getValue(); - - CodeBlock.Builder groupCode = CodeBlock.builder() - .addStatement("List<$T> $LList = new $T<>()", mInterceptor, group, ArrayList.class); - for (TypeElement type: interceptorList) { - mLog.i(String.format("------ Processing %s ------", type.getSimpleName())); - groupCode.addStatement("$LList.add(new $T())", group, type); - } - - rootCode.add(groupCode.build()); - rootCode.addStatement("this.mMap.put($S, $LList)", group, group); - } - - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - MethodSpec registerMethod = MethodSpec.methodBuilder("onRegister") - .addAnnotation(Override.class) - .addModifiers(Modifier.PUBLIC) - .addParameter(mContext, "context") - .addParameter(mString, "group") - .addParameter(mRegisterType, "register") - .addStatement("List<$T> list = mMap.get(group)", mInterceptor) - .beginControlFlow("if(list == null)") - .addStatement("list = new $T<>()", ArrayList.class) - .endControlFlow() - .addStatement("List<$T> defaultList = mMap.get($S)", mInterceptor, "default") - .beginControlFlow("if(defaultList != null && !defaultList.isEmpty())") - .addStatement("list.addAll(defaultList)") - .endControlFlow() - .beginControlFlow("if(list != null && !list.isEmpty())") - .beginControlFlow("for ($T interceptor : list)", mInterceptor) - .addStatement("register.addInterceptor(interceptor)") - .endControlFlow() - .endControlFlow() - .build(); - - TypeSpec adapterClass = TypeSpec.classBuilder("InterceptorRegister") - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addSuperinterface(mOnRegisterType) - .addField(mapField) - .addMethod(rootMethod) - .addMethod(registerMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(registerPackageName, adapterClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private String getGroup(TypeElement type) { - Interceptor interceptor = type.getAnnotation(Interceptor.class); - if (interceptor != null) { - return interceptor.value(); - } - throw new IllegalStateException(String.format("The type is not a Interceptor: %1$s.", type)); - } - - @Override - protected void addAnnotation(Set> classSet) { - classSet.add(Interceptor.class); - classSet.add(AppInfo.class); - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/ResolverProcessor.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/ResolverProcessor.java deleted file mode 100644 index a6c892945f7434e658c7b07ec6f5864e87580578..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/ResolverProcessor.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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 com.google.auto.service.AutoService; -import com.squareup.javapoet.*; -import com.yanzhenjie.andserver.annotation.AppInfo; -import com.yanzhenjie.andserver.annotation.Resolver; -import com.yanzhenjie.andserver.processor.util.Constants; -import com.yanzhenjie.andserver.processor.util.Logger; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.Validate; - -import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Created by Zhenjie Yan on 2018/9/11. - */ -//@AutoService(Processor.class) -//@SupportedSourceVersion(SourceVersion.RELEASE_8) -//@SupportedAnnotationTypes({"com.yanzhenjie.andserver.annotation.Resolver","com.yanzhenjie.andserver.annotation.AppInfo"}) -public class ResolverProcessor extends BaseProcessor { - - private Filer mFiler; - private Elements mElements; - private Logger mLog; - - private TypeName mContext; - private TypeName mOnRegisterType; - private TypeName mRegisterType; - - private TypeName mResolver; - - private TypeName mString; - - @Override - public synchronized void init(ProcessingEnvironment processingEnv) { - mFiler = processingEnv.getFiler(); - mElements = processingEnv.getElementUtils(); - mLog = new Logger(processingEnv.getMessager()); - - mContext = TypeName.get(mElements.getTypeElement(Constants.CONTEXT_TYPE).asType()); - mOnRegisterType = TypeName.get(mElements.getTypeElement(Constants.ON_REGISTER_TYPE).asType()); - mRegisterType = TypeName.get(mElements.getTypeElement(Constants.REGISTER_TYPE).asType()); - - mResolver = TypeName.get(mElements.getTypeElement(Constants.RESOLVER_TYPE).asType()); - - mString = TypeName.get(String.class); - } - - @Override - public boolean process(Set set, RoundEnvironment roundEnv) { - if (CollectionUtils.isEmpty(set)) { - return false; - } - - Set appSet = roundEnv.getElementsAnnotatedWith(AppInfo.class); - String registerPackageName = getRegisterPackageName(appSet); - - Map resolverMap = findAnnotation(roundEnv); - if (!resolverMap.isEmpty()) { - createRegister(registerPackageName, resolverMap); - } - return true; - } - - private Map findAnnotation(RoundEnvironment roundEnv) { - Set set = roundEnv.getElementsAnnotatedWith(Resolver.class); - Map resolverMap = new HashMap<>(); - - for (Element element: set) { - if (element instanceof TypeElement) { - TypeElement typeElement = (TypeElement) element; - - Set modifiers = typeElement.getModifiers(); - Validate.isTrue(modifiers.contains(Modifier.PUBLIC), "The modifier public is missing on %s.", - typeElement.getQualifiedName()); - - List interfaces = typeElement.getInterfaces(); - if (CollectionUtils.isEmpty(interfaces)) { - mLog.w(String.format( - "The annotation Resolver must be used in a subclass of [ExceptionResolver] on %s.", - typeElement.getQualifiedName())); - continue; - } - for (TypeMirror typeMirror: interfaces) { - if (mResolver.equals(TypeName.get(typeMirror))) { - resolverMap.put(getGroup(typeElement), typeElement); - break; - } else { - mLog.w(String.format( - "The annotation Resolver must be used in a subclass of [ExceptionResolver] on %s.", - typeElement.getQualifiedName())); - } - } - } - } - return resolverMap; - } - - private void createRegister(String registerPackageName, Map resolverMap) { - TypeName typeName = ParameterizedTypeName.get(ClassName.get(Map.class), mString, mResolver); - FieldSpec mapField = FieldSpec.builder(typeName, "mMap", Modifier.PRIVATE).build(); - - CodeBlock.Builder rootCode = CodeBlock.builder().addStatement("this.mMap = new $T<>()", HashMap.class); - for (Map.Entry entry: resolverMap.entrySet()) { - String group = entry.getKey(); - TypeElement resolver = entry.getValue(); - mLog.i(String.format("------ Processing %s ------", resolver.getSimpleName())); - rootCode.addStatement("this.mMap.put($S, new $T())", group, resolver); - } - - MethodSpec rootMethod = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC) - .addCode(rootCode.build()) - .build(); - - MethodSpec registerMethod = MethodSpec.methodBuilder("onRegister") - .addAnnotation(Override.class) - .addModifiers(Modifier.PUBLIC) - .addParameter(mContext, "context") - .addParameter(mString, "group") - .addParameter(mRegisterType, "register") - .addStatement("$T resolver = mMap.get(group)", mResolver) - .beginControlFlow("if(resolver == null)") - .addStatement("resolver = mMap.get($S)", "default") - .endControlFlow() - .beginControlFlow("if(resolver != null)") - .addStatement("register.setResolver(resolver)") - .endControlFlow() - .build(); - - TypeSpec adapterClass = TypeSpec.classBuilder("ResolverRegister") - .addJavadoc(Constants.DOC_EDIT_WARN) - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .addSuperinterface(mOnRegisterType) - .addField(mapField) - .addMethod(rootMethod) - .addMethod(registerMethod) - .build(); - - JavaFile javaFile = JavaFile.builder(registerPackageName, adapterClass).build(); - try { - javaFile.writeTo(mFiler); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - - private String getGroup(TypeElement type) { - Resolver resolver = type.getAnnotation(Resolver.class); - if (resolver != null) { - return resolver.value(); - } - throw new IllegalStateException(String.format("The type is not a Resolver: %1$s.", type)); - } - - @Override - protected void addAnnotation(Set> classSet) { - classSet.add(Resolver.class); - classSet.add(AppInfo.class); - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/CrossOriginImpl.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/CrossOriginImpl.java deleted file mode 100644 index ecf47c34be39d71302bf704ad25a7f89e1520e28..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/CrossOriginImpl.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.cross; - - -import com.yanzhenjie.andserver.annotation.CrossOrigin; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 10/19/20. - */ -public class CrossOriginImpl { - - private CrossOrigin mCrossOrigin; - - public CrossOriginImpl(CrossOrigin crossOrigin) { - this.mCrossOrigin = crossOrigin; - } - - public String[] value() { - if (mCrossOrigin != null) { - return mCrossOrigin.value(); - } - return new String[0]; - } - - public String[] origins() { - if (mCrossOrigin != null) { - return mCrossOrigin.origins(); - } - return new String[0]; - } - - public String[] allowedHeaders() { - if (mCrossOrigin != null) { - return mCrossOrigin.allowedHeaders(); - } - return new String[0]; - } - - public String[] exposedHeaders() { - if (mCrossOrigin != null) { - return mCrossOrigin.exposedHeaders(); - } - return new String[0]; - } - - public String[] methods() { - if (mCrossOrigin != null) { - RequestMethod[] methods = mCrossOrigin.methods(); - String[] textMethods = new String[methods.length]; - if (methods != null && methods.length > 0) { - for (int i = 0; i < textMethods.length; i++) { - textMethods[i] = methods[i].value(); - } - } - return textMethods; - } - return new String[0]; - } - - public String allowCredentials() { - if (mCrossOrigin != null) { - return mCrossOrigin.allowCredentials(); - } - return ""; - } - - public long maxAge() { - if (mCrossOrigin != null) { - return mCrossOrigin.maxAge(); - } - return -1; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/MergeCrossOrigin.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/MergeCrossOrigin.java deleted file mode 100644 index c5e33df3e121916caafffb5ce425b10eb73cb4ca..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/cross/MergeCrossOrigin.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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.cross; - - -import com.yanzhenjie.andserver.processor.util.Utils; - -/** - * Created by Zhenjie Yan on 10/18/20. - */ -public class MergeCrossOrigin { - - private CrossOriginImpl mParent; - private CrossOriginImpl mChild; - - private String[] mOrigins; - private String[] mAllowedHeaders; - private String[] mExposedHeaders; - private String[] mMethods; - - public MergeCrossOrigin(CrossOriginImpl parent, CrossOriginImpl child) { - this.mParent = parent; - this.mChild = child; - } - - public String[] value() { - return origins(); - } - - public String[] origins() { - if (mOrigins != null) { - return mOrigins; - } - - String[] pOrigins = mParent.origins(); - if (pOrigins == null || pOrigins.length == 0) { - pOrigins = mParent.value(); - } - String[] cOrigins = mChild.origins(); - if (cOrigins == null || cOrigins.length == 0) { - cOrigins = mChild.value(); - } - - mOrigins = Utils.mergeRepeat(pOrigins, cOrigins, true); - return mOrigins; - } - - public String[] allowedHeaders() { - if (mAllowedHeaders != null) { - return mAllowedHeaders; - } - - String[] pHeaders = mParent.allowedHeaders(); - String[] cHeaders = mChild.allowedHeaders(); - mAllowedHeaders = Utils.mergeRepeat(pHeaders, cHeaders, true); - return mAllowedHeaders; - } - - public String[] exposedHeaders() { - if (mExposedHeaders != null) { - return mExposedHeaders; - } - - String[] pHeaders = mParent.exposedHeaders(); - String[] cHeaders = mChild.exposedHeaders(); - mExposedHeaders = Utils.mergeRepeat(pHeaders, cHeaders, true); - return mExposedHeaders; - } - - public String[] methods() { - if (mMethods != null) { - return mMethods; - } - - String[] pMethods = mParent.methods(); - String[] cMethods = mChild.methods(); - mMethods = Utils.mergeRepeat(pMethods, cMethods, true); - return mMethods; - } - - public boolean allowCredentials() { - String cCredentials = mChild.allowCredentials(); - if (cCredentials != null && cCredentials.length() >0) { - return Boolean.parseBoolean(cCredentials); - } - - String pCredentials = mChild.allowCredentials(); - if (pCredentials != null && pCredentials.length() >0) { - return Boolean.parseBoolean(pCredentials); - } - - return true; - } - - public long maxAge() { - long cMaxAge = mChild.maxAge(); - if (cMaxAge >= 0) { - return cMaxAge; - } - - long pMaxAge = mParent.maxAge(); - if (pMaxAge >= 0) { - return pMaxAge; - } - - return 1800; - } - -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Any.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Any.java deleted file mode 100644 index df19e81f35bdbdc08d6f653f1a1d0cfbf207d46f..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Any.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Any implements Mapping { - - private RequestMapping mMapping; - private boolean isRest; - - public Any(RequestMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - RequestMethod[] methods = mMapping.method(); - String[] textMethods = new String[methods.length]; - if (textMethods != null && textMethods.length > 0) { - for (int i = 0; i < textMethods.length; i++) { - textMethods[i] = methods[i].value(); - } - } - return textMethods; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Delete.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Delete.java deleted file mode 100644 index 59c660b1e3467ca85dd1d3626c5dca2070f01211..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Delete.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.DeleteMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Delete implements Mapping { - - private DeleteMapping mMapping; - private boolean isRest; - - public Delete(DeleteMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - return new String[]{RequestMethod.DELETE.value()}; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Get.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Get.java deleted file mode 100644 index 82599a02da7caed2e4a7a0c889c9665bbe88ff54..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Get.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.GetMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Get implements Mapping { - - private GetMapping mMapping; - private boolean isRest; - - public Get(GetMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - return new String[]{RequestMethod.GET.value()}; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Mapping.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Mapping.java deleted file mode 100644 index 64a3604ad592167a668a45aae6852ed4dd073d95..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Mapping.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.RequestMapping; -import com.yanzhenjie.andserver.annotation.ResponseBody; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public interface Mapping { - - /** - * {@link RequestMapping#value()} - */ - String[] value(); - - /** - * {@link RequestMapping#path()} - */ - String[] path(); - - /** - * {@link RequestMapping#method()} - */ - String[] method(); - - /** - * {@link RequestMapping#params()} - */ - String[] params(); - - /** - * {@link RequestMapping#headers()} - */ - String[] headers(); - - /** - * {@link RequestMapping#consumes()} - */ - String[] consumes(); - - /** - * {@link RequestMapping#produces()} - */ - String[] produces(); - - /** - * {@link ResponseBody} - */ - boolean isRest(); -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Merge.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Merge.java deleted file mode 100644 index cc0875ad8821697e4dbb65714019d2b21173ba95..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Merge.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.RequestMethod; -import com.yanzhenjie.andserver.processor.util.Utils; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Zhenjie Yan on 2018/9/8. - */ -public class Merge implements Mapping { - - private String[] mPaths; - private String[] mMethods; - private String[] mParams; - private String[] mHeaders; - private String[] mConsumes; - private String[] mProduces; - - private Mapping mParent; - private Mapping mChild; - - public Merge(Mapping parent, Mapping child) { - this.mParent = parent; - this.mChild = child; - } - - @Override - public String[] value() { - return path(); - } - - @Override - public String[] path() { - if (mPaths != null) { - return mPaths; - } - - String[] pPaths = mParent.path(); - if (pPaths == null || pPaths.length == 0) { - pPaths = mParent.value(); - } - String[] cPaths = mChild.path(); - if (cPaths == null || cPaths.length == 0) { - cPaths = mChild.value(); - } - - if (pPaths != null && pPaths.length > 0) { - List paths = new ArrayList<>(); - for (String pPath : pPaths) { - for (String cPath : cPaths) { - String path = pPath + cPath; - paths.add(path); - - if (path.endsWith("/")) { - if (path.length() > 1) { - String copyPath = path.substring(0, path.length() - 1); - paths.add(copyPath); - } - } else { - String copyPath = path + "/"; - paths.add(copyPath); - } - } - } - mPaths = paths.toArray(new String[0]); - } else { - if (cPaths != null && cPaths.length > 0) { - List paths = new ArrayList<>(); - for (String cPath : cPaths) { - paths.add(cPath); - - if (cPath.endsWith("/")) { - if (cPath.length() > 1) { - String copyPath = cPath.substring(0, cPath.length() - 1); - paths.add(copyPath); - } - } else { - String copyPath = cPath + "/"; - paths.add(copyPath); - } - } - mPaths = paths.toArray(new String[0]); - } else { - mPaths = cPaths; - } - } - - mPaths = Utils.mergeRepeat(mPaths, null, false); - return mPaths; - } - - @Override - public String[] method() { - if (mMethods != null) { - return mMethods; - } - - String[] pMethods = mParent.method(); - String[] cMethods = mChild.method(); - mMethods = Utils.mergeRepeat(pMethods, cMethods, true); - if (mMethods == null || mMethods.length == 0) { - mMethods = new String[]{RequestMethod.GET.value()}; - } - return mMethods; - } - - @Override - public String[] params() { - if (mParams != null) { - return mParams; - } - - String[] pParams = mParent.params(); - String[] cParams = mChild.params(); - mParams = Utils.mergeRepeat(pParams, cParams, false); - return mParams; - } - - @Override - public String[] headers() { - if (mHeaders != null) { - return mHeaders; - } - - String[] pHeaders = mParent.headers(); - String[] cHeaders = mChild.headers(); - mHeaders = Utils.mergeRepeat(pHeaders, cHeaders, true); - return mHeaders; - } - - @Override - public String[] consumes() { - if (mConsumes != null) { - return mConsumes; - } - - String[] pConsumes = mParent.consumes(); - String[] cConsumes = mChild.consumes(); - mConsumes = Utils.mergeRepeat(pConsumes, cConsumes, true); - return mConsumes; - } - - @Override - public String[] produces() { - if (mProduces != null) { - return mProduces; - } - - String[] pProduces = mParent.produces(); - String[] cProduces = mChild.produces(); - mProduces = Utils.mergeRepeat(pProduces, cProduces, true); - return mProduces; - } - - @Override - public boolean isRest() { - return mParent.isRest() || mChild.isRest(); - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Null.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Null.java deleted file mode 100644 index 0879dd166f499b09df0d9a7b692c8d23b6cc8700..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Null.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - -/** - * Created by Zhenjie Yan on 2018/9/17. - */ -public class Null implements Mapping { - - private boolean isRest; - - public Null() { - this(false); - } - - public Null(boolean isRest) { - this.isRest = isRest; - } - - @Override - public String[] value() { - return new String[0]; - } - - @Override - public String[] path() { - return new String[0]; - } - - @Override - public String[] method() { - return new String[0]; - } - - @Override - public String[] params() { - return new String[0]; - } - - @Override - public String[] headers() { - return new String[0]; - } - - @Override - public String[] consumes() { - return new String[0]; - } - - @Override - public String[] produces() { - return new String[0]; - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Patch.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Patch.java deleted file mode 100644 index a155493446ebb1acb219abba799a59479a24b805..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Patch.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.PatchMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Patch implements Mapping { - - private PatchMapping mMapping; - private boolean isRest; - - public Patch(PatchMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - return new String[]{RequestMethod.PATCH.value()}; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Post.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Post.java deleted file mode 100644 index 7c1279d8421620b4f8bf7f05eb11463aca730da4..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Post.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.PostMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Post implements Mapping { - - private PostMapping mMapping; - private boolean isRest; - - public Post(PostMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - return new String[]{RequestMethod.POST.value()}; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Put.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Put.java deleted file mode 100644 index 8f3c8b7efe59783b4b59cada350837ab1106132c..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/mapping/Put.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan. - * - * 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.mapping; - - -import com.yanzhenjie.andserver.annotation.PutMapping; -import com.yanzhenjie.andserver.annotation.RequestMethod; - -/** - * Created by Zhenjie Yan on 2018/6/16. - */ -public class Put implements Mapping { - - private PutMapping mMapping; - private boolean isRest; - - public Put(PutMapping mapping, boolean rest) { - this.mMapping = mapping; - this.isRest = rest; - } - - @Override - public String[] value() { - return mMapping.value(); - } - - @Override - public String[] path() { - return mMapping.path(); - } - - @Override - public String[] method() { - return new String[]{RequestMethod.PUT.value()}; - } - - @Override - public String[] params() { - return mMapping.params(); - } - - @Override - public String[] headers() { - return mMapping.headers(); - } - - @Override - public String[] consumes() { - return mMapping.consumes(); - } - - @Override - public String[] produces() { - return mMapping.produces(); - } - - @Override - public boolean isRest() { - return isRest; - } -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constants.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constants.java deleted file mode 100644 index 4548f48eecbf28a72fc289b117847c25f8dfbb82..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Constants.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 Zhenjie Yan - * - * 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; - -/** - * Created by Zhenjie Yan on 2018/2/6. - */ -public interface Constants { - - String DOC_EDIT_WARN = "This file was generated by AndServer automatically and you should NOT edit it."; - - String CONTEXT_TYPE = "ohos.app.Context"; - String LOG_TYPE = "android.util.Log"; - String TEXT_UTILS_TYPE = "com.yanzhenjie.andserver.util.TextUtils"; - String PACKAGE_NAME = "com.yanzhenjie.andserver"; - String ANDSERVER_TYPE = PACKAGE_NAME + ".AndServer"; - String TYPE_WRAPPER_TYPE = PACKAGE_NAME + ".util.TypeWrapper"; - String MEDIA_TYPE = PACKAGE_NAME + ".util.MediaType"; - String ON_REGISTER_TYPE = PACKAGE_NAME + ".register.OnRegister"; - String REGISTER_TYPE = PACKAGE_NAME + ".register.Register"; - - String BODY_MISSING = PACKAGE_NAME + ".error.BodyMissingException"; - String COOKIE_MISSING = PACKAGE_NAME + ".error.CookieMissingException"; - String PARAM_MISSING = PACKAGE_NAME + ".error.ParamMissingException"; - String HEADER_MISSING = PACKAGE_NAME + ".error.HeaderMissingException"; - String PATH_MISSING = PACKAGE_NAME + ".error.PathMissingException"; - String PARAM_ERROR = PACKAGE_NAME + ".error.ParamValidateException"; - - String ADAPTER_TYPE = PACKAGE_NAME + ".framework.handler.HandlerAdapter"; - String MAPPING_ADAPTER_TYPE = PACKAGE_NAME + ".framework.handler.MappingAdapter"; - String HANDLER_TYPE = PACKAGE_NAME + ".framework.handler.RequestHandler"; - String MAPPING_HANDLER_TYPE = PACKAGE_NAME + ".framework.handler.MappingHandler"; - String VIEW_TYPE = PACKAGE_NAME + ".framework.view.View"; - String VIEW_TYPE_OBJECT = PACKAGE_NAME + ".framework.view.ObjectView"; - String CONVERTER_TYPE = PACKAGE_NAME + ".framework.MessageConverter"; - String RESOLVER_TYPE = PACKAGE_NAME + ".framework.ExceptionResolver"; - String INTERCEPTOR_TYPE = PACKAGE_NAME + ".framework.HandlerInterceptor"; - String WEBSITE_TYPE = PACKAGE_NAME + ".framework.website.Website"; - String CONFIG_TYPE = PACKAGE_NAME + ".framework.config.WebConfig"; - String CONFIG_DELEGATE_TYPE = PACKAGE_NAME + ".framework.config.Delegate"; - String CONFIG_MULTIPART_TYPE = PACKAGE_NAME + ".framework.config.Multipart"; - - String REQUEST_TYPE = PACKAGE_NAME + ".http.HttpRequest"; - String MULTIPART_REQUEST_TYPE = PACKAGE_NAME + ".http.multipart.MultipartRequest"; - String RESPONSE_TYPE = PACKAGE_NAME + ".http.HttpResponse"; - String HTTP_METHOD_TYPE = PACKAGE_NAME + ".http.HttpMethod"; - String HTTP_HEADERS_TYPE = PACKAGE_NAME + ".http.HttpHeaders"; - String SESSION_TYPE = PACKAGE_NAME + ".http.session.Session"; - String REQUEST_BODY_TYPE = PACKAGE_NAME + ".http.RequestBody"; - String MULTIPART_FILE_TYPE = PACKAGE_NAME + ".http.multipart.MultipartFile"; - - String ADDITION_TYPE = PACKAGE_NAME + ".framework.mapping.Addition"; - String CROSS_ORIGIN_TYPE = PACKAGE_NAME + ".framework.cross.CrossOrigin"; - String MAPPING_TYPE = PACKAGE_NAME + ".framework.mapping.Mapping"; - String MIME_MAPPING_TYPE = PACKAGE_NAME + ".framework.mapping.Mime"; - String METHOD_MAPPING_TYPE = PACKAGE_NAME + ".framework.mapping.Method"; - String PAIR_MAPPING_TYPE = PACKAGE_NAME + ".framework.mapping.Pair"; - String PATH_MAPPING_TYPE = PACKAGE_NAME + ".framework.mapping.Path"; -} \ 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 deleted file mode 100644 index 84633fa929a13cd291d5d2bbd113185259519124..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Logger.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © Zhenjie Yan - * - * 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 javax.annotation.processing.Messager; -import javax.tools.Diagnostic; - -/** - * Created by Zhenjie Yan on 2018/2/5. - */ -public class Logger { - - private Messager mMessager; - - public Logger(Messager messager) { - this.mMessager = messager; - } - - public void i(CharSequence info) { - if (info != null && info.length() > 0) { - mMessager.printMessage(Diagnostic.Kind.NOTE, info); - } - } - - public void e(CharSequence error) { - if (error != null && error.length() > 0) { - 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 (warning != null && warning.length() > 0) { - 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/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Patterns.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Patterns.java deleted file mode 100644 index 242c83f3bc839afd7aea1085085bf57c70ee0529..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Patterns.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2018 Zhenjie Yan. - * - * 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; - -/** - * Created by Zhenjie Yan on 2018/9/5. - */ -public interface Patterns { - - String WORD = "[a-zA-Z0-9_\\-%s]%s"; - - String PATH_0 = String.format(WORD, "\\u4e00-\\u9fa5\\.", "*"); - String PATH_1 = String.format(WORD, "\\u4e00-\\u9fa5\\.", "+"); - String PATH_STRICT = String.format("((/%s)|((/%s)+))|((/%s)+/)", PATH_0, PATH_1, PATH_1); - String PATH_BLURRED_MAYBE = String.format("((/%s)+)(((/%s)|(/%s/)|(/\\{%s})|(/\\{%s}/))+)", PATH_1, PATH_1, PATH_1, PATH_1, PATH_1); - String PATH_BLURRED_INCLUDE = String.format("/\\{%s}", PATH_1); - - String PAIR_KEY = String.format(WORD, "", "+"); - String PAIR_VALUE = "(.)*"; - String PAIR_KEY_VALUE = String.format("(%s)(=)(%s)", PAIR_KEY, PAIR_VALUE); - String PAIR_NO_KEY = String.format("!%s", PAIR_KEY); - String PAIR_NO_VALUE = String.format("(%s)(!=)(%s)", PAIR_KEY, PATH_1); -} \ No newline at end of file diff --git a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Utils.java b/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Utils.java deleted file mode 100644 index 7f1e3ea2e22f3019922b5d51b9daeb3f6cb6916f..0000000000000000000000000000000000000000 --- a/processor/src/main/java/com/yanzhenjie/andserver/processor/util/Utils.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2020 Zhenjie Yan. - * - * 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 java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Created by Zhenjie Yan on 10/19/20. - */ -public class Utils { - - public static String[] mergeRepeat(String[] parents, String[] children, boolean ignoreCap) { - Map map = new HashMap<>(); - if (parents != null && parents.length > 0) { - for (String parent : parents) { - map.put(ignoreCap ? parent.toLowerCase() : parent, parent); - } - } - if (children != null && children.length > 0) { - for (String child : children) { - map.put(ignoreCap ? child.toLowerCase() : child, child); - } - } - Collection values = map.values(); - return values.toArray(new String[0]); - } - -} \ No newline at end of file diff --git a/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors b/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors deleted file mode 100644 index 0f361f317de0473f7f309f1a7be536c588711b0b..0000000000000000000000000000000000000000 --- a/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors +++ /dev/null @@ -1,5 +0,0 @@ -com.yanzhenjie.andserver.processor.ControllerProcessor,isolating -com.yanzhenjie.andserver.processor.ConverterProcessor,isolating -com.yanzhenjie.andserver.processor.InterceptorProcessor,isolating -com.yanzhenjie.andserver.processor.ResolverProcessor,isolating -com.yanzhenjie.andserver.processor.ConfigProcessor,isolating \ No newline at end of file diff --git a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor deleted file mode 100644 index 003636212c03ac7f45bf7470ecc2ee96be0614b7..0000000000000000000000000000000000000000 --- a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ /dev/null @@ -1,5 +0,0 @@ -com.yanzhenjie.andserver.processor.ControllerProcessor -com.yanzhenjie.andserver.processor.ConverterProcessor -com.yanzhenjie.andserver.processor.InterceptorProcessor -com.yanzhenjie.andserver.processor.ResolverProcessor -com.yanzhenjie.andserver.processor.ConfigProcessor \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 38e93cf9b117a30ce48308df67c7598a4766670b..4773db73233a570c2d0c01a22e75321acfbf7a07 100755 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':entry', ':annotation', ':processor', ':plugin', ':api' +include ':entry'