[LIB-8] Modify URL entity annotation functionality
[snooker-score-api.git] / src / main / java / org / hedgecode / snooker / json / JsonURLEntity.java
1 /*
2  * Copyright (c) 2017-2020. Developed by Hedgecode.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.hedgecode.snooker.json;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.hedgecode.snooker.SnookerURLUtils;
27 import org.hedgecode.snooker.annotation.IsURL;
28 import org.hedgecode.snooker.annotation.WithHTMLTags;
29 import org.hedgecode.snooker.api.APIException;
30 import org.hedgecode.snooker.api.SnookerURL;
31 import org.hedgecode.snooker.api.URLEntity;
32
33 /**
34  * Abstract URL Entity.
35  *
36  * @author Dmitry Samoshin aka gotty
37  */
38 public abstract class JsonURLEntity implements URLEntity {
39
40     @Override
41     public List<SnookerURL> getLinks() throws APIException {
42         List<SnookerURL> links = null;
43         Map<String, String> htmlStrings = getAnnotatedStrings(WithHTMLTags.class);
44         if (!htmlStrings.isEmpty()) {
45             links = SnookerURLUtils.parseUrls(htmlStrings);
46         }
47         return links;
48     }
49
50     @Override
51     public List<SnookerURL> getURLs() throws APIException {
52         List<SnookerURL> urls = null;
53         Map<String, String> urlStrings = getAnnotatedStrings(IsURL.class);
54         urlStrings.putAll(getAnnotatedMethodStrings(IsURL.class));
55         if (!urlStrings.isEmpty()) {
56             urls = SnookerURLUtils.assignUrls(urlStrings);
57         }
58         return urls;
59     }
60
61     @Override
62     public SnookerURL getURL(String name) throws APIException {
63         String urlString = getAnnotatedString(IsURL.class, name);
64         if (urlString == null) {
65             urlString = getAnnotatedMethodString(IsURL.class, name);
66         }
67         if (urlString != null && !urlString.isEmpty()) {
68             return SnookerURLUtils.assignUrl(name, urlString);
69         }
70         return null;
71     }
72
73     @Override
74     public String withoutTags(String name) throws APIException {
75         String tagString = getAnnotatedString(WithHTMLTags.class, name);
76         if (tagString != null && !tagString.isEmpty()) {
77             return SnookerURLUtils.cutTags(tagString);
78         }
79         return null;
80     }
81
82     private Map<String, String> getAnnotatedStrings(
83             Class<? extends Annotation> annotationClass
84     ) {
85         Map<String, String> result = new HashMap<>();
86         Class<?> clazz = getClass();
87         for (Field field : clazz.getDeclaredFields()) {
88             if (field.isAnnotationPresent(annotationClass)
89                     && field.getType().equals(String.class))
90             {
91                 field.setAccessible(true);
92                 try {
93                     result.put(
94                             field.getName(),
95                             (String) field.get(this)
96                     );
97                 } catch (ReflectiveOperationException ignored) {
98                 }
99             }
100         }
101         return result;
102     }
103
104     private String getAnnotatedString(
105             Class<? extends Annotation> annotationClass,
106             String fieldName
107     ) {
108         String result = null;
109         try {
110             Class<?> clazz = getClass();
111             Field field = clazz.getDeclaredField(fieldName);
112             if (field.isAnnotationPresent(annotationClass)
113                     && field.getType().equals(String.class))
114             {
115                 field.setAccessible(true);
116                 result = (String) field.get(this);
117             }
118         } catch (ReflectiveOperationException ignored) {
119         }
120         return result;
121     }
122
123     private Map<String, String> getAnnotatedMethodStrings(
124             Class<? extends Annotation> annotationClass
125     ) {
126         Map<String, String> result = new HashMap<>();
127         Class<?> clazz = getClass();
128         for (Method method : clazz.getDeclaredMethods()) {
129             if (method.isAnnotationPresent(annotationClass)
130                     && method.getParameterCount() == 0
131                     && method.getReturnType().equals(String.class))
132             {
133                 try {
134                     result.put(
135                             method.getName(),
136                             (String) method.invoke(this)
137                     );
138                 } catch (ReflectiveOperationException ignored) {
139                 }
140             }
141         }
142         return result;
143     }
144
145     private String getAnnotatedMethodString(
146             Class<? extends Annotation> annotationClass,
147             String methodName
148     ) {
149         String result = null;
150         try {
151             Class<?> clazz = getClass();
152             Method method = clazz.getDeclaredMethod(methodName);
153             if (method.isAnnotationPresent(annotationClass)
154                     && method.getReturnType().equals(String.class))
155             {
156                 result = (String) method.invoke(this);
157             }
158         } catch (ReflectiveOperationException ignored) {
159         }
160         return result;
161     }
162
163 }