1
|
package eu.dnetlib.enabling.is.controller;
|
2
|
|
3
|
import java.io.StringReader;
|
4
|
import java.util.Collections;
|
5
|
import java.util.Date;
|
6
|
import java.util.HashMap;
|
7
|
import java.util.List;
|
8
|
import java.util.Map;
|
9
|
import java.util.UUID;
|
10
|
|
11
|
import org.apache.commons.lang3.StringUtils;
|
12
|
import org.apache.commons.lang3.math.NumberUtils;
|
13
|
import org.apache.commons.logging.Log;
|
14
|
import org.apache.commons.logging.LogFactory;
|
15
|
import org.dom4j.Document;
|
16
|
import org.dom4j.DocumentException;
|
17
|
import org.dom4j.io.SAXReader;
|
18
|
import org.springframework.beans.factory.annotation.Autowired;
|
19
|
import org.springframework.http.MediaType;
|
20
|
import org.springframework.web.bind.annotation.PathVariable;
|
21
|
import org.springframework.web.bind.annotation.RequestBody;
|
22
|
import org.springframework.web.bind.annotation.RequestMapping;
|
23
|
import org.springframework.web.bind.annotation.RequestMethod;
|
24
|
import org.springframework.web.bind.annotation.RequestParam;
|
25
|
import org.springframework.web.bind.annotation.RestController;
|
26
|
|
27
|
import com.google.common.collect.Lists;
|
28
|
|
29
|
import eu.dnetlib.enabling.annotations.DnetService;
|
30
|
import eu.dnetlib.enabling.annotations.DnetServiceType;
|
31
|
import eu.dnetlib.enabling.is.DnetInformationServiceException;
|
32
|
import eu.dnetlib.enabling.is.store.ISStore;
|
33
|
import eu.dnetlib.enabling.is.tools.DatabaseUtils;
|
34
|
import eu.dnetlib.enabling.is.tools.ProfileValidator;
|
35
|
import eu.dnetlib.miscutils.datetime.DateUtils;
|
36
|
import eu.dnetlib.services.BaseService;
|
37
|
|
38
|
@RestController
|
39
|
@RequestMapping("/is")
|
40
|
@DnetService(DnetServiceType.is)
|
41
|
public class InformationServiceController extends BaseService {
|
42
|
|
43
|
private static final Log log = LogFactory.getLog(InformationServiceController.class);
|
44
|
|
45
|
@Autowired
|
46
|
private ISStore isStore;
|
47
|
|
48
|
@Autowired
|
49
|
private ProfileValidator profileValidator;
|
50
|
|
51
|
@RequestMapping(value = "schema/{name}", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
|
52
|
public String getSchema(@PathVariable("name") final String resourceType) throws DnetInformationServiceException {
|
53
|
if (StringUtils.isBlank(resourceType)) { throw new DnetInformationServiceException("Invalid resourceType"); }
|
54
|
|
55
|
return isStore.getXML(resourceType, DatabaseUtils.SCHEMAS_COLLECTION);
|
56
|
}
|
57
|
|
58
|
@RequestMapping("schemas")
|
59
|
public List<String> listSchemas() throws DnetInformationServiceException {
|
60
|
return isStore.getFileNames(DatabaseUtils.SCHEMAS_COLLECTION);
|
61
|
}
|
62
|
|
63
|
@RequestMapping(value = "schema/{name}", method = RequestMethod.POST)
|
64
|
public boolean registerSchema(@PathVariable("name") final String resourceType, @RequestBody final String resourceSchema)
|
65
|
throws DnetInformationServiceException {
|
66
|
return isStore.insertXML(resourceType, DatabaseUtils.SCHEMAS_COLLECTION, resourceSchema);
|
67
|
}
|
68
|
|
69
|
@RequestMapping(value = "schema/{name}", method = RequestMethod.DELETE)
|
70
|
public boolean deleteSchema(@PathVariable("name") final String resourceType) throws DnetInformationServiceException {
|
71
|
return isStore.deleteXML(resourceType, DatabaseUtils.SCHEMAS_COLLECTION);
|
72
|
}
|
73
|
|
74
|
@RequestMapping("profiles/{kind}/{type}")
|
75
|
public List<String> listProfiles(@PathVariable("kind") final String kind, @PathVariable("type") final String type) throws DnetInformationServiceException {
|
76
|
return isStore.getFileNames(DatabaseUtils.getCollection(kind, type));
|
77
|
}
|
78
|
|
79
|
@RequestMapping(value = "profile", method = RequestMethod.POST)
|
80
|
public String registerProfile(@RequestBody final String profile) throws DnetInformationServiceException {
|
81
|
log.debug("registering profile");
|
82
|
|
83
|
try {
|
84
|
|
85
|
final Document doc = (new SAXReader()).read(new StringReader(profile));
|
86
|
|
87
|
final String kind = doc.valueOf("/profile/kind").trim();
|
88
|
final String type = doc.valueOf("/profile/type").trim();
|
89
|
final String fileName = UUID.randomUUID().toString();
|
90
|
|
91
|
final String newId = DatabaseUtils.composeResourceId(kind, type, fileName);
|
92
|
final String date = new DateUtils(new Date()).getDateAsISO8601String();
|
93
|
|
94
|
doc.selectSingleNode("/profile/id").setText(newId);
|
95
|
doc.selectSingleNode("/profile/date").setText(date);
|
96
|
|
97
|
final String finalDoc = doc.asXML();
|
98
|
|
99
|
if (profileValidator.isValid(type, finalDoc)) {
|
100
|
isStore.insertXML(fileName, DatabaseUtils.getCollection(kind, type), finalDoc);
|
101
|
return newId;
|
102
|
} else {
|
103
|
throw new DnetInformationServiceException("Invalid profile");
|
104
|
}
|
105
|
} catch (final DocumentException e) {
|
106
|
throw new DnetInformationServiceException(e);
|
107
|
}
|
108
|
}
|
109
|
|
110
|
@RequestMapping("collections")
|
111
|
public List<CollectionDesc> listCollections() throws Exception {
|
112
|
final String xquery = "for $kind in xmldb:get-child-collections('/db/DRIVER') " +
|
113
|
"for $type in xmldb:get-child-collections(concat('/db/DRIVER/', $kind)) " +
|
114
|
"return concat ($kind, ' @@@ ', $type, ' @@@ ', count(xmldb:get-child-resources(concat('/db/DRIVER/', $kind, '/', $type))))";
|
115
|
|
116
|
final Map<String, CollectionDesc> map = new HashMap<>();
|
117
|
for (final String s : isStore.quickSearchXML(xquery)) {
|
118
|
final String[] arr = s.split("@@@");
|
119
|
final String kind = arr[0].trim();
|
120
|
final String type = arr[1].trim();
|
121
|
final int size = NumberUtils.toInt(arr[2].trim(), 0);
|
122
|
if (!map.containsKey(kind)) {
|
123
|
map.put(kind, new CollectionDesc(kind));
|
124
|
}
|
125
|
map.get(kind).addType(type, size);
|
126
|
}
|
127
|
|
128
|
final List<CollectionDesc> res = Lists.newArrayList(map.values());
|
129
|
for (final CollectionDesc d : res) {
|
130
|
Collections.sort(d.getTypes());
|
131
|
}
|
132
|
Collections.sort(res);
|
133
|
|
134
|
return res;
|
135
|
}
|
136
|
|
137
|
@RequestMapping(value = "profile/{kind}/{type}/{fileName}", method = RequestMethod.GET, produces = MediaType.APPLICATION_XML_VALUE)
|
138
|
public String getProfile(@PathVariable("kind") final String kind, @PathVariable("type") final String type, @PathVariable("fileName") final String fileName)
|
139
|
throws DnetInformationServiceException {
|
140
|
|
141
|
final String res = isStore.getXML(fileName, DatabaseUtils.getCollection(kind, type));
|
142
|
|
143
|
if (StringUtils.isBlank(res)) {
|
144
|
throw new DnetInformationServiceException("document " + DatabaseUtils.composeResourceId(kind, type, fileName) + " not found");
|
145
|
} else {
|
146
|
return res;
|
147
|
}
|
148
|
|
149
|
}
|
150
|
|
151
|
@RequestMapping(value = "profile/{kind}/{type}/{fileName}", method = RequestMethod.POST)
|
152
|
public boolean updateProfile(@PathVariable("kind") final String kind,
|
153
|
@PathVariable("type") final String type,
|
154
|
@PathVariable("fileName") final String fileName,
|
155
|
@RequestBody final String profile) throws DnetInformationServiceException {
|
156
|
try {
|
157
|
final String resId = DatabaseUtils.composeResourceId(kind, type, fileName);
|
158
|
|
159
|
final String coll = DatabaseUtils.getCollection(kind, type);
|
160
|
|
161
|
final String oldProfileSrc = isStore.getXML(fileName, coll);
|
162
|
|
163
|
if (oldProfileSrc == null) { throw new DnetInformationServiceException("cannot update a non existing profile " + resId); }
|
164
|
|
165
|
final Document doc = (new SAXReader()).read(new StringReader(profile));
|
166
|
|
167
|
final String date = new DateUtils(new Date()).getDateAsISO8601String();
|
168
|
|
169
|
doc.selectSingleNode("/profile/id").setText(resId);
|
170
|
doc.selectSingleNode("/profile/date").setText(date);
|
171
|
|
172
|
final String finalDoc = doc.asXML();
|
173
|
|
174
|
if (profileValidator.isValid(type, finalDoc)) {
|
175
|
isStore.insertXML(fileName, coll, finalDoc);
|
176
|
return true;
|
177
|
} else {
|
178
|
throw new DnetInformationServiceException("Invalid profile");
|
179
|
}
|
180
|
} catch (final DocumentException e) {
|
181
|
throw new DnetInformationServiceException(e);
|
182
|
}
|
183
|
}
|
184
|
|
185
|
@RequestMapping(value = "profile/{kind}/{type}/{fileName}", method = RequestMethod.DELETE)
|
186
|
public boolean deleteProfile(@PathVariable("kind") final String kind,
|
187
|
@PathVariable("type") final String type,
|
188
|
@PathVariable("fileName") final String fileName) throws DnetInformationServiceException {
|
189
|
|
190
|
final boolean res = isStore.deleteXML(fileName, DatabaseUtils.getCollection(kind, type));
|
191
|
|
192
|
if (!res) { throw new DnetInformationServiceException("document " + DatabaseUtils.composeResourceId(kind, type, fileName) + " not found"); }
|
193
|
|
194
|
return true;
|
195
|
}
|
196
|
|
197
|
@RequestMapping("xupdate")
|
198
|
public boolean executeXUpdate(@RequestParam("q") final String xquery) throws DnetInformationServiceException {
|
199
|
return isStore.executeXUpdate(xquery);
|
200
|
}
|
201
|
|
202
|
@RequestMapping("find")
|
203
|
public List<String> find(@RequestParam("q") final String xquery) throws DnetInformationServiceException {
|
204
|
return isStore.quickSearchXML(xquery);
|
205
|
}
|
206
|
|
207
|
}
|