Project

General

Profile

1
package eu.dnetlib.functionality.modular.ui.mdstore;
2

    
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
import java.util.Map;
7
import java.util.stream.Collectors;
8
import javax.annotation.Resource;
9
import javax.xml.ws.wsaddressing.W3CEndpointReference;
10

    
11
import com.google.common.base.Function;
12
import com.google.common.collect.Lists;
13
import com.google.common.collect.Maps;
14
import eu.dnetlib.data.mdstore.DocumentNotFoundException;
15
import eu.dnetlib.data.mdstore.MDStoreService;
16
import eu.dnetlib.data.mdstore.modular.MDFormatDescription;
17
import eu.dnetlib.data.mdstore.modular.MDStoreUtils;
18
import eu.dnetlib.data.mdstore.modular.ModularMDStoreService;
19
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
20
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
21
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
22
import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
23
import eu.dnetlib.functionality.modular.ui.mdstore.model.MDStoreInfo;
24
import eu.dnetlib.functionality.modular.ui.mdstore.model.MDStoreResult;
25
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
26
import org.apache.commons.logging.Log;
27
import org.apache.commons.logging.LogFactory;
28
import org.springframework.beans.factory.annotation.Autowired;
29
import org.springframework.beans.factory.annotation.Value;
30
import org.springframework.core.io.ClassPathResource;
31
import org.springframework.stereotype.Controller;
32
import org.springframework.ui.ModelMap;
33
import org.springframework.web.bind.annotation.*;
34

    
35
/**
36
 * The Class MDStoreServiceInternalController.
37
 */
38
@Controller
39
public class MDStoreServiceInternalController {
40

    
41
    /**
42
     * The Constant log.
43
     */
44
    private static final Log log = LogFactory.getLog(MDStoreServiceInternalController.class);
45

    
46
    @Value("${dnet.modular.ui.mdstore.xslt.record2document}")
47
    private String recordXsltClasspath;
48

    
49
    /**
50
     * The lookup locator.
51
     */
52
    @Resource
53
    private UniqueServiceLocator serviceLocator;
54

    
55
    @Autowired
56
    private MDStoreUtils mdStoreUtils;
57

    
58
    @Resource
59
    private ResultSetClientFactory resultSetClientFactory;
60

    
61
    @Autowired
62
    private ModularMDStoreService mdStoreService;
63

    
64

    
65
    private Map<String, Info> datasourceCache;
66

    
67
    /**
68
     * List md stores.
69
     *
70
     * @param map the map
71
     * @return the list
72
     * @throws Exception the exception
73
     */
74
    @RequestMapping(value = "/ui/mdstore/listMDStores.do")
75
    @ResponseBody
76

    
77
    public List<MDStoreInfo> listMDStores(final ModelMap map) throws Exception {
78
        if (datasourceCache == null) {
79
            datasourceCache = datasourceFromMdStore();
80
        }
81

    
82

    
83
        final String xquery = "for $x in  collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType')  let $format := $x//METADATA_FORMAT  "
84
                + "let $layout := $x//METADATA_FORMAT_LAYOUT  let $interpretation :=$x//METADATA_FORMAT_INTERPRETATION "
85
                + "let $uri := $x//RESOURCE_URI/@value/string()  let $id := $x//RESOURCE_IDENTIFIER/@value/string() "
86
                + "let $lastDate := $x//LAST_STORAGE_DATE  let $size :=$x//NUMBER_OF_RECORDS "
87
                + "return concat($uri,'@::@',$id,'@::@',$format,'(-)',$layout, '(-)',$interpretation,'@::@',$lastDate,'@::@',$size) ";
88

    
89
        log.debug("Executing lookup query" + xquery);
90
        return Lists.transform(serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xquery), input -> {
91
            MDStoreInfo mdStoreInfo = MDStoreInfo.fromXqueryResult(input);
92
            Info currentInfo = datasourceCache.get(mdStoreInfo.getId());
93
            if (currentInfo != null) {
94
                Map<String, String> datasourcesInvolved = mdStoreInfo.getDatasourcesInvolved();
95
                if (datasourcesInvolved == null) {
96
                    datasourcesInvolved = Maps.newHashMap();
97
                    mdStoreInfo.setDatasourcesInvolved(datasourcesInvolved);
98
                }
99
                datasourcesInvolved.put("datasourceId", currentInfo.getDatasourceId());
100
                datasourcesInvolved.put("datasourceName", currentInfo.getDatasourceName());
101

    
102
            }
103
            return mdStoreInfo;
104
        });
105
    }
106

    
107
    @RequestMapping(value = "/ui/mdstore/reloadInfo")
108
    @ResponseBody
109
    public List<MDStoreInfo> reloadInfo(final ModelMap map) throws Exception {
110
        datasourceCache = null;
111
        return listMDStores(map);
112
    }
113

    
114
    @RequestMapping(value = "/ui/mdstore/getMdStoreInfo.do")
115
    @ResponseBody
116
    public MDStoreInfo getMdStoreInfo(final ModelMap map, @RequestParam(value = "id", required = true) final String profileId) throws Exception {
117

    
118
        final MDStoreInfo mdStoreInfo = retrieveMDStoreInfo(profileId);
119
        List<MDFormatDescription> indexFields = mdStoreUtils.getField(mdStoreInfo.getFormat(), mdStoreInfo.getLayout());
120
        List<String> idFields;
121
        if (indexFields != null) {
122
            idFields = indexFields.stream().map(MDFormatDescription::getName).collect(Collectors.toList());
123
            mdStoreInfo.setIndexFields(idFields);
124
        }
125
        return mdStoreInfo;
126
    }
127

    
128

    
129
    @RequestMapping(value = "/ui/mdstore/findRecords", method = RequestMethod.POST)
130
    @ResponseBody
131
    public MDStoreResult findRecords(final ModelMap map,
132
                                     @RequestBody final Map<String, String> queryParam) throws Exception {
133

    
134
        if (!queryParam.containsKey("mdId")) throw new MDStoreUIException("mdId parameters expected");
135

    
136
        final String mdId = queryParam.get("mdId");
137

    
138
        int offset = 0;
139

    
140
        if (queryParam.containsKey("page")) {
141
            try {
142
                offset = Integer.parseInt(queryParam.get("page"));
143
                queryParam.remove("page");
144
            } catch (Exception e) {
145
                log.error("Error on parsing page " + queryParam.get("page"));
146
            }
147
        }
148
        queryParam.remove("mdId");
149

    
150
        final MDStoreResult res = new MDStoreResult();
151
        res.setResult(mdStoreService.getMDStoreRecords(mdId, 10, offset, queryParam));
152

    
153

    
154
        //TERRIBLE HACK SHAME SANDRO SHAME!
155
        int count = 0;
156
        try {
157
            count = Integer.parseInt(queryParam.get("count"));
158
        } catch (Exception e) {
159
            log.error(e);
160
        }
161

    
162
        res.setCount(count);
163

    
164
        return res;
165
    }
166

    
167
    @RequestMapping(value = "/ui/mdstore/mdStoreResults")
168
    @ResponseBody
169
    public MDStoreResult getMDStoreResults(final ModelMap map,
170
                                           @RequestParam(value = "mdId", required = true) final String mdId,
171
                                           @RequestParam(value = "from", required = true) final int from,
172
                                           @RequestParam(value = "id_query", required = false) final String idToQuery,
173
                                           @RequestParam(value = "free_query", required = false) final String freeQuery) throws Exception {
174

    
175
        MDStoreService mdService = serviceLocator.getService(MDStoreService.class, mdId);
176
        ClassPathResource cpr = new ClassPathResource(recordXsltClasspath);
177
        ApplyXslt xslt = new ApplyXslt(cpr);
178
        MDStoreResult resultValues = new MDStoreResult();
179
        resultValues.setCount(getMdStoreInfo(map, mdId).getSize());
180

    
181
        if (idToQuery != null && !idToQuery.isEmpty()) {
182
            try {
183
                String record = mdService.deliverRecord(mdId, idToQuery);
184
                resultValues.setResult(Lists.newArrayList(xslt.evaluate(record)));
185
                return resultValues;
186
            } catch (DocumentNotFoundException e) {
187
                return null;
188
            }
189
        }
190

    
191

    
192
        W3CEndpointReference epr = mdService.deliverMDRecords(mdId, null, null, null);
193
        Iterable<String> result = resultSetClientFactory.getClient(epr);
194
        List<String> convertedList = new ArrayList<String>();
195
        Iterator<String> it = result.iterator();
196
        int currentCounter = 0;
197
        while (currentCounter < from) {
198
            if (it.hasNext()) {
199
                it.next();
200
                currentCounter++;
201
            } else {
202
                resultValues.setResult(convertedList);
203
                return resultValues;
204
            }
205
        }
206

    
207
        for (int i = 0; i < 10; i++) {
208
            if (it.hasNext()) {
209
//                convertedList.add(xslt.evaluate(it.next()));
210
                convertedList.add(it.next());
211
            } else {
212
                break;
213
            }
214
        }
215
        resultValues.setResult(convertedList);
216
        return resultValues;
217
    }
218

    
219

    
220
    private Map<String, Info> datasourceFromMdStore() {
221
        final String query = "for $x in collection('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType') where $x[.//PARAM/@category/string()='MDSTORE_ID'] " +
222
                "return concat($x//PARAM[./@name='providerId'][1]/string(), '<::>',$x//PARAM[./@name='providerName'][1]/string(), '<::>', " +
223
                "string-join($x//PARAM[./@category/string()='MDSTORE_ID']/string(), '--'))";
224
        final ISLookUpService lookupService = serviceLocator.getService(ISLookUpService.class);
225
        try {
226
            Map<String, Info> result = Maps.newHashMap();
227
            List<String> results = lookupService.quickSearchProfile(query);
228
            for (String item : results) {
229
                String[] splitted = item.split("<::>");
230
                if (splitted != null && splitted.length == 3) {
231
                    final Info currentInfo = new Info();
232
                    currentInfo.setDatasourceId(splitted[0]);
233
                    currentInfo.setDatasourceName(splitted[1]);
234
                    final String[] mdstores = splitted[2].split("--");
235
                    if (mdstores != null) {
236
                        for (String mdstore : mdstores) {
237
                            result.put(mdstore, currentInfo);
238
                        }
239
                    }
240
                }
241
            }
242
            return result;
243
        } catch (ISLookUpException e) {
244
            log.error(e);
245
            return null;
246
        }
247
    }
248

    
249
    private MDStoreInfo retrieveMDStoreInfo(final String identifier) {
250

    
251
        MDStoreInfo result = null;
252
        try {
253
            result = null;
254
            final String xquery = " for $x in collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType') "
255
                    + " where $x//RESOURCE_IDENTIFIER/@value/string()=\"%s\"   return concat($x//RESOURCE_URI/@value/string() "
256
                    + ", '@::@',$x//RESOURCE_IDENTIFIER/@value/string() ,'@::@',$x//METADATA_FORMAT,'(-)',$x//METADATA_FORMAT_LAYOUT,  "
257
                    + " '(-)', $x//METADATA_FORMAT_INTERPRETATION ,'@::@',$x//LAST_STORAGE_DATE,'@::@',$x//NUMBER_OF_RECORDS)";
258

    
259
            List<String> results = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(String.format(xquery, identifier));
260
            if (results != null && !results.isEmpty()) {
261
                result = MDStoreInfo.fromXqueryResult(results.get(0));
262
            }
263
        } catch (ISLookUpException e) {
264
            log.error(String.format("Error on getting information for mdstore with identifier: %s", identifier), e);
265
        }
266

    
267
        return result;
268
    }
269

    
270

    
271
    private Map<String, String> findDatasourceNameAssociatedToMdStore(final String mdStoreId) throws ISLookUpException {
272
        final String baseQuery = "for $x in collection('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType') where $x[.//PARAM/string()='%s'] return concat($x//PARAM[./@name='providerId'][1]/string(), '<::>',$x//PARAM[./@name='providerName'][1]/string())";
273
        final ISLookUpService lookupService = serviceLocator.getService(ISLookUpService.class);
274
        List<String> result = lookupService.quickSearchProfile(String.format(baseQuery, mdStoreId));
275
        Map<String, String> datasources = Maps.newHashMap();
276
        for (String item : result) {
277
            String[] splitted = item.split("<::>");
278
            if (splitted != null && splitted.length == 2) {
279
                datasources.put(splitted[0], splitted[1]);
280
            }
281
        }
282
        return datasources;
283
    }
284

    
285

    
286
    class Info {
287
        private String datasourceId;
288
        private String datasourceName;
289
        private String mdStoreId;
290

    
291

    
292
        public String getDatasourceName() {
293
            return datasourceName;
294
        }
295

    
296
        public void setDatasourceName(String datasourceName) {
297
            this.datasourceName = datasourceName;
298
        }
299

    
300
        public String getDatasourceId() {
301
            return datasourceId;
302
        }
303

    
304
        public void setDatasourceId(String datasourceId) {
305
            this.datasourceId = datasourceId;
306
        }
307

    
308
        public String getMdStoreId() {
309
            return mdStoreId;
310
        }
311

    
312
        public void setMdStoreId(String mdStoreId) {
313
            this.mdStoreId = mdStoreId;
314
        }
315
    }
316
}
(2-2/3)