1 package net.sumaris.server.http.graphql.technical;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import io.leangen.graphql.annotations.GraphQLArgument;
27 import io.leangen.graphql.annotations.GraphQLEnvironment;
28 import io.leangen.graphql.annotations.GraphQLMutation;
29 import io.leangen.graphql.annotations.GraphQLQuery;
30 import net.sumaris.core.service.administration.DepartmentService;
31 import net.sumaris.core.service.technical.SoftwareService;
32 import net.sumaris.core.vo.administration.user.DepartmentVO;
33 import net.sumaris.core.vo.technical.ConfigurationVO;
34 import net.sumaris.core.vo.technical.SoftwareVO;
35 import net.sumaris.server.config.SumarisServerConfiguration;
36 import net.sumaris.server.config.SumarisServerConfigurationOption;
37 import net.sumaris.server.http.graphql.administration.AdministrationGraphQLService;
38 import net.sumaris.server.http.rest.RestPaths;
39 import net.sumaris.server.service.administration.ImageService;
40 import org.apache.commons.collections4.MapUtils;
41 import org.apache.commons.lang3.ArrayUtils;
42 import org.apache.commons.lang3.StringUtils;
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45 import org.springframework.beans.factory.annotation.Autowired;
46 import org.springframework.stereotype.Service;
47 import org.springframework.transaction.annotation.Transactional;
48
49 import java.io.IOException;
50 import java.util.List;
51 import java.util.Objects;
52 import java.util.Set;
53 import java.util.stream.Collectors;
54 import java.util.stream.Stream;
55
56 @Service
57 @Transactional
58 public class ConfigurationGraphQLService {
59
60 public static final String JSON_START_SUFFIX = "{";
61
62 private static final Log log = LogFactory.getLog(ConfigurationGraphQLService.class);
63
64 @Autowired
65 private SoftwareService service;
66
67 @Autowired
68 private AdministrationGraphQLService administrationGraphQLService;
69
70 @Autowired
71 private DepartmentService departmentService;
72
73 @Autowired
74 private ObjectMapper objectMapper;
75
76 private String imageUrl;
77
78 @Autowired
79 public ConfigurationGraphQLService(SumarisServerConfiguration config) {
80 super();
81
82
83 imageUrl = config.getServerUrl() + RestPaths.IMAGE_PATH;
84 }
85
86 @GraphQLQuery(name = "configuration", description = "A software configuration")
87 @Transactional(readOnly = true)
88 public ConfigurationVO getConfiguration(
89 @GraphQLArgument(name = "software") String softwareLabel,
90 @GraphQLEnvironment() Set<String> fields
91 ){
92 SoftwareVO software = StringUtils.isBlank(softwareLabel) ? service.getDefault() : service.get(softwareLabel);
93 return toConfiguration(software, fields);
94 }
95
96 @GraphQLMutation(name = "saveConfiguration", description = "Save a software configuration")
97 public ConfigurationVO save(@GraphQLArgument(name = "config") ConfigurationVO configuration,
98 @GraphQLEnvironment() Set<String> fields){
99
100 SoftwareVO software = service.save(configuration);
101 return toConfiguration(software, fields);
102 }
103
104
105
106 protected ConfigurationVO toConfiguration(SoftwareVO software, Set<String> fields) {
107 if (software == null) return null;
108 ConfigurationVOonfigurationVO.html#ConfigurationVO">ConfigurationVO result = new ConfigurationVO(software);
109
110
111 if (fields.contains(ConfigurationVO.Fields.PARTNERS)) {
112 this.fillPartners(result);
113 }
114
115
116 if (fields.contains(ConfigurationVO.Fields.BACKGROUND_IMAGES)) {
117 this.fillBackgroundImages(result);
118 }
119
120
121 String logoUri = getProperty(result, SumarisServerConfigurationOption.SITE_LOGO_SMALL.getKey());
122 if (StringUtils.isNotBlank(logoUri)) {
123 String logoUrl = getImageUrl(logoUri);
124 result.getProperties().put(
125 SumarisServerConfigurationOption.SITE_LOGO_SMALL.getKey(),
126 logoUrl);
127 result.setSmallLogo(logoUrl);
128 }
129
130
131 String logoLargeUri = getProperty(result, SumarisServerConfigurationOption.LOGO_LARGE.getKey());
132 if (StringUtils.isNotBlank(logoLargeUri)) {
133 String logoLargeUrl = getImageUrl(logoLargeUri);
134 result.getProperties().put(
135 SumarisServerConfigurationOption.LOGO_LARGE.getKey(),
136 logoLargeUrl);
137 result.setLargeLogo(logoLargeUrl);
138 }
139
140
141 String faviconUri = getProperty(result, SumarisServerConfigurationOption.SITE_FAVICON.getKey());
142 if (StringUtils.isNotBlank(faviconUri)) {
143 String faviconUrl = getImageUrl(faviconUri);
144 result.getProperties().put(SumarisServerConfigurationOption.SITE_FAVICON.getKey(), faviconUrl);
145 }
146
147 return result;
148 }
149
150 protected String getProperty(ConfigurationVO config, String propertyName) {
151 return MapUtils.getString(config.getProperties(), propertyName);
152 }
153
154 protected String[] getPropertyAsArray(ConfigurationVO config, String propertyName) {
155 String value = getProperty(config, propertyName);
156
157 if (StringUtils.isBlank(value)) return null;
158
159 try {
160 return objectMapper.readValue(value, String[].class);
161 } catch (IOException e) {
162 log.warn(String.format("Unable to deserialize array value for option {%s}: %s", propertyName, value));
163 return value.split(",");
164 }
165 }
166
167 protected void fillPartners(ConfigurationVO result) {
168 String[] values = getPropertyAsArray(result, SumarisServerConfigurationOption.SITE_PARTNER_DEPARTMENTS.getKey());
169
170 if (ArrayUtils.isNotEmpty(values)) {
171
172
173 int[] ids = Stream.of(values)
174 .map(String::trim)
175 .mapToInt(uri -> {
176 if (uri.startsWith(DepartmentService.URI_DEPARTMENT_SUFFIX)) {
177 return Integer.parseInt(uri.substring(DepartmentService.URI_DEPARTMENT_SUFFIX.length()));
178 }
179 return -1;
180 })
181 .filter(id -> id >= 0).toArray();
182 List<DepartmentVO> departments = departmentService.getByIds(ids);
183
184
185 List<DepartmentVO> deserializeDepartments = Stream.of(values)
186 .map(String::trim)
187 .map(jsonStr -> {
188 if (jsonStr.startsWith(JSON_START_SUFFIX)) {
189 try {
190 return objectMapper.readValue(jsonStr, DepartmentVO.class);
191 } catch(IOException e) {
192 log.warn(String.format("Unable to deserialize a value for option {%s}: %s", SumarisServerConfigurationOption.SITE_PARTNER_DEPARTMENTS.getKey(), jsonStr), e);
193 return null;
194 }
195 }
196 return null;
197 }).filter(Objects::nonNull).collect(Collectors.toList());
198
199 departments = Stream.concat(departments.stream(), deserializeDepartments.stream())
200 .map(administrationGraphQLService::fillLogo)
201 .collect(Collectors.toList());
202 result.setPartners(departments);
203 }
204 }
205
206 protected void fillBackgroundImages(ConfigurationVO result) {
207 String[] values = getPropertyAsArray(result, SumarisServerConfigurationOption.SITE_BACKGROUND_IMAGES.getKey());
208
209 if (ArrayUtils.isNotEmpty(values)) {
210
211 List<String> urls = Stream.of(values)
212 .map(this::getImageUrl)
213 .collect(Collectors.toList());
214 result.setBackgroundImages(urls);
215 }
216 }
217
218 protected String getImageUrl(String imageUri) {
219 if (StringUtils.isBlank(imageUri)) return null;
220
221
222 if (imageUri.startsWith(ImageService.URI_IMAGE_SUFFIX)) {
223 return imageUrl.replace("{id}", imageUri.substring(ImageService.URI_IMAGE_SUFFIX.length()));
224 }
225
226 return imageUri;
227 }
228
229 }