Project

General

Profile

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

    
3
import com.google.common.collect.Lists;
4
import com.google.common.collect.Maps;
5
import com.google.gson.Gson;
6
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
7
import eu.dnetlib.functionality.modular.ui.AbstractAjaxController;
8
import eu.dnetlib.functionality.modular.ui.lightui.LightUIUtils;
9
import eu.dnetlib.functionality.modular.ui.lightui.clients.ISLookupLightUIClient;
10
import eu.dnetlib.functionality.modular.ui.patcheditor.client.IndexPatchEditorClient;
11
import eu.dnetlib.functionality.modular.ui.patcheditor.converters.EfgAvCreationConverter;
12
import eu.dnetlib.functionality.modular.ui.patcheditor.converters.EfgNonAvCreationConverter;
13
import eu.dnetlib.functionality.modular.ui.patcheditor.exceptions.PatchEditorException;
14
import eu.dnetlib.functionality.modular.ui.patcheditor.record.LSCH;
15
import eu.dnetlib.functionality.modular.ui.patcheditor.record.Patch;
16
import eu.dnetlib.functionality.modular.ui.patcheditor.record.PatchManager;
17
import eu.dnetlib.functionality.modular.ui.patcheditor.record.PatchedRecord;
18
import eu.dnetlib.functionality.modular.ui.patcheditor.record.UIAction;
19
import eu.dnetlib.functionality.modular.ui.patcheditor.record.UIAction.EntityTypes;
20
import eu.dnetlib.functionality.modular.ui.vocabularies.model.Relation;
21
import eu.dnetlib.functionality.modular.ui.vocabularies.model.Synonym;
22
import eu.dnetlib.functionality.modular.ui.vocabularies.model.Term;
23
import eu.dnetlib.functionality.modular.ui.vocabularies.persistence.VocabularyException;
24
import eu.dnetlib.rmi.enabling.ISLookUpException;
25
import eu.dnetlib.rmi.enabling.ISLookUpService;
26
import java.io.BufferedReader;
27
import java.io.IOException;
28
import java.io.InputStreamReader;
29
import java.io.StringReader;
30
import java.util.ArrayList;
31
import java.util.Collections;
32
import java.util.List;
33
import java.util.Map;
34
import javax.annotation.Resource;
35
import javax.servlet.http.HttpSession;
36
import org.apache.commons.logging.Log;
37
import org.apache.commons.logging.LogFactory;
38
import org.dom4j.Document;
39
import org.dom4j.DocumentException;
40
import org.dom4j.Element;
41
import org.dom4j.Node;
42
import org.dom4j.io.SAXReader;
43
import org.springframework.beans.factory.annotation.Autowired;
44
import org.springframework.stereotype.Controller;
45
import org.springframework.ui.ModelMap;
46
import org.springframework.web.bind.annotation.RequestMapping;
47
import org.springframework.web.bind.annotation.RequestMethod;
48
import org.springframework.web.bind.annotation.RequestParam;
49
import org.springframework.web.bind.annotation.ResponseBody;
50

    
51
@Controller
52
public class PatchEditorController extends AbstractAjaxController {
53

    
54
	private static final Log log = LogFactory.getLog(PatchEditorController.class);
55

    
56
	@Resource
57
	private PatchManager patchManager;
58

    
59
	@Autowired
60
	private UniqueServiceLocator serviceLocator;
61

    
62
	@Autowired
63
	private IndexPatchEditorClient indexPatchEditorClient;
64

    
65
	@javax.annotation.Resource
66
	private ISLookupLightUIClient isLookupClient;
67

    
68
	@RequestMapping(path = "/ui/patcheditor/titleTypes", method = RequestMethod.GET)
69
	public @ResponseBody List<Term> getTitleTypes() throws Exception {
70
		final List<Term> terms = getVocabularies("AVTitleType");
71
		return terms;
72
	}
73

    
74
	@RequestMapping(path = "/ui/patcheditor/languages", method = RequestMethod.GET)
75
	public @ResponseBody List<Term> getLanguages() throws Exception {
76
		final List<Term> terms = getVocabularies("Names of Languages");
77
		return terms;
78
	}
79

    
80
	@RequestMapping(path = "/ui/patcheditor/countries", method = RequestMethod.GET)
81
	public @ResponseBody List<Term> getCountries() throws Exception {
82
		final List<Term> terms = getVocabularies("Iso3166-1CountryCS");
83
		return terms;
84
	}
85

    
86
	@RequestMapping(path = "/ui/patcheditor/keywordTypes", method = RequestMethod.GET)
87
	public @ResponseBody List<Term> getKeywordTypes() throws Exception {
88
		final List<Term> terms = getVocabularies("KeywordType");
89
		return terms;
90
	}
91

    
92
	@RequestMapping(path = "/ui/patcheditor/sounds", method = RequestMethod.GET)
93
	public @ResponseBody List<Term> getSounds() throws Exception {
94
		final List<Term> terms = getVocabularies("Sound");
95
		return terms;
96
	}
97

    
98
	@RequestMapping(path = "/ui/patcheditor/colours", method = RequestMethod.GET)
99
	public @ResponseBody List<Term> getColours() throws Exception {
100
		final List<Term> terms = getVocabularies("Colour");
101
		return terms;
102
	}
103

    
104
	@RequestMapping(path = "/ui/patcheditor/languageUsages", method = RequestMethod.GET)
105
	public @ResponseBody List<Term> getLanguageUsages() throws Exception {
106
		final List<Term> terms = getVocabularies("LanguageUsage");
107
		return terms;
108
	}
109

    
110
	@RequestMapping(path = "/ui/patcheditor/descriptionTypes", method = RequestMethod.GET)
111
	public @ResponseBody List<Term> getDescriptionTypes() throws Exception {
112
		final List<Term> terms = getVocabularies("DescriptionType");
113
		return terms;
114
	}
115

    
116
	@RequestMapping(path = "/ui/patcheditor/rightsStatus", method = RequestMethod.GET)
117
	public @ResponseBody List<Term> getRightsStatus() throws Exception {
118
		final List<Term> terms = getVocabularies("RightsStatus");
119
		return terms;
120
	}
121

    
122
	@RequestMapping(path = "/ui/patcheditor/gauge", method = RequestMethod.GET)
123
	public @ResponseBody List<Term> getGauge() throws Exception {
124
		final List<Term> terms = getVocabularies("Gauge");
125
		return terms;
126
	}
127

    
128
	@RequestMapping(path = "/ui/patcheditor/lsch", method = RequestMethod.GET)
129
	public @ResponseBody List<LSCH> getLSCH() throws Exception {
130
		final List<LSCH> lschs = loadLSCH();
131
		return lschs;
132
	}
133

    
134
	@RequestMapping(path = "/ui/patcheditor/record", method = RequestMethod.GET)
135
	public @ResponseBody Map getRecord(@RequestParam(value = "recordId", required = true) final String recordId) throws Exception {
136

    
137
		final PatchedRecord patchedRecord = createPatchedRecord(recordId);
138
		patchedRecord.getData().put("repositoryId", patchedRecord.getRepositoryId());
139
		patchedRecord.getData().put("entityType", patchedRecord.getType());
140
		return patchedRecord.getData();
141
	}
142

    
143
	@RequestMapping(path = "/ui/patcheditor/existPatchNotIndexed", method = RequestMethod.GET)
144
	public @ResponseBody String existPatchNotIndexed(@RequestParam(value = "repositoryId", required = true) final String repositoryId,
145
			@RequestParam(value = "recordId", required = true) final String recordId) throws Exception {
146

    
147
		final boolean existPatchNotIndexed = patchManager.existPatchNotIndexed(repositoryId, recordId);
148
		if (existPatchNotIndexed) { return "true"; }
149
		return "";
150
	}
151

    
152
	@RequestMapping(path = "/ui/applyPatches.do", method = RequestMethod.POST)
153
	public @ResponseBody String applyPatches(ModelMap map,
154
			HttpSession httpSession,
155
			@RequestParam(value = "id", required = true) String id,
156
			@RequestParam(value = "patches", required = true) String patches) {
157
		generateActions(map, httpSession, id, patches);
158
		return "ok";
159
	}
160

    
161
	private List<Term> getVocabularies(final String codeValue) throws PatchEditorException {
162
		List<Term> terms = null;
163
		try {
164
			final String query =
165
					"for $x in collection('/db/DRIVER/VocabularyDSResources/VocabularyDSResourceType') where ($x//VOCABULARY_NAME/@code='" + codeValue
166
							+ "') return $x";
167
			final List<String> countries = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query);
168
			terms = getTerms(countries.get(0));
169
		} catch (final ISLookUpException e) {
170
			throw new PatchEditorException(e);
171
		}
172
		return terms;
173
	}
174

    
175
	private List<Term> getTerms(final String vocabulary) throws PatchEditorException {
176
		try {
177
			final Document doc = new SAXReader().read(new StringReader(vocabulary));
178
			final Map<String, Term> terms = Maps.newHashMap();
179
			for (final Object t : doc.selectNodes("//TERM")) {
180
				final Element termNode = (Element) t;
181
				final String code = termNode.valueOf("@code");
182
				if (!terms.containsKey(code)) {
183
					final Term term = new Term();
184
					term.setEnglishName(termNode.valueOf("@english_name"));
185
					term.setNativeName(termNode.valueOf("@native_name"));
186
					term.setEncoding(termNode.valueOf("@encoding"));
187
					term.setCode(code);
188
					term.setSynonyms(new ArrayList<Synonym>());
189
					term.setRelations(new ArrayList<Relation>());
190
					terms.put(code, term);
191
				}
192
				final Term term = terms.get(code);
193
				for (final Object s : termNode.selectNodes(".//SYNONYM")) {
194
					final Element synNode = (Element) s;
195
					final Synonym syn = new Synonym();
196
					syn.setTerm(synNode.valueOf("@term"));
197
					syn.setEncoding(synNode.valueOf("@encoding"));
198
					term.getSynonyms().add(syn);
199
				}
200
				for (final Object r : termNode.selectNodes(".//RELATION")) {
201
					final Element relNode = (Element) r;
202
					final Relation rel = new Relation();
203
					rel.setCode(relNode.valueOf("@code"));
204
					rel.setType(relNode.valueOf("@type"));
205
					term.getRelations().add(rel);
206
				}
207
				Collections.sort(term.getSynonyms());
208
				Collections.sort(term.getRelations());
209
			}
210
			final List<Term> list = Lists.newArrayList(terms.values());
211
			Collections.sort(list);
212
			return list;
213
		} catch (final DocumentException e) {
214
			throw new PatchEditorException(new VocabularyException(e));
215
		}
216
	}
217

    
218
	private List<LSCH> loadLSCH() {
219
		try {
220
			final BufferedReader br =
221
					new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/eu/dnetlib/web/LSCH.csv")));
222
			final Gson g = new Gson();
223
			String s;
224

    
225
			s = br.readLine();
226

    
227
			final List<LSCH> lschs = new ArrayList<LSCH>();
228

    
229
			while (s != null) {
230
				final String[] lsch = s.split(";");
231
				lschs.add(new LSCH(lsch[1], lsch[0], lsch[2]));
232
				s = br.readLine();
233
			}
234
			return lschs;
235
		} catch (final IOException e) {
236

    
237
			return null;
238
		}
239

    
240
	}
241

    
242
	private Node getConfigurationNode(final String lightuiId, final String xpath, final String id) throws Exception {
243
		final SAXReader reader = new SAXReader();
244
		final Document doc = reader.read(new StringReader(isLookupClient.getLightUiProfile(lightuiId)));
245
		return doc.selectSingleNode(xpath);
246
	}
247

    
248
	private String getDocument(final String lightuiId, String field, final String id) throws Exception {
249
		final Node searchNode = getConfigurationNode(lightuiId, "//DOCUMENT", id);
250
		return indexPatchEditorClient.getDocument(LightUIUtils.calculateIndexConfiguration(searchNode), field, id);
251
	}
252

    
253
	public PatchedRecord createPatchedRecord(final String recordId) throws PatchEditorException {
254
		try {
255
			final String lightuiId = "eagle";
256
			final String field = "objidentifier";
257
			final String recordPlain = getDocument(lightuiId, field, recordId);
258
			final SAXReader reader = new SAXReader();
259
			final Document doc = reader.read(new StringReader(recordPlain));
260
			final String repoId = doc.valueOf("//*[local-name()='repositoryId']");
261
			final String type = doc.valueOf("local-name(//*[local-name()='efgEntity']/*)");
262
			Map patchedRecordData = null;
263
			if (type.equals("avcreation")) {
264
				final EfgAvCreationConverter conv = new EfgAvCreationConverter();
265
				patchedRecordData = conv.calculateJsonForPatchEdit(doc.getRootElement());
266
			} else if (type.equals("nonavcreation")) {
267
				final EfgNonAvCreationConverter conv = new EfgNonAvCreationConverter();
268
				patchedRecordData = conv.calculateJsonForPatchEdit(doc.getRootElement());
269
			} else {
270
				throw new PatchEditorException("patches can be only applied for avcreation and nonavcreation types");
271
			}
272
			return new PatchedRecord(recordId, repoId, patchedRecordData, type, new ArrayList<Patch>());
273
		} catch (final Exception e) {
274
			throw new PatchEditorException(e);
275
		}
276
	}
277

    
278
	private void generateActions(ModelMap map,
279
			HttpSession httpSession,
280
			String recordId,
281
			String jsonPatches) {
282
		try {
283
			final PatchedRecord record = createPatchedRecord(recordId);
284
			final String type = record.getType();
285
			final EntityTypes entityType = UIAction.EntityTypes.valueOf(type);
286

    
287
			final List<Patch> patches = new ArrayList<Patch>();
288

    
289
			UIAction[] arrayAction;
290
			arrayAction = new Gson().fromJson(jsonPatches, UIAction[].class);
291

    
292
			for (final UIAction element : arrayAction) {
293
				element.setEntityType(entityType);
294
				patches.addAll(element.asPatches());
295
			}
296

    
297
			record.setPatches(patches);
298

    
299
			patchManager.commit(record);
300

    
301
			map.addAttribute("response", "OK");
302
		} catch (final Exception e) {
303
			log.warn(e);
304

    
305
			map.addAttribute("response", "FAIL");
306
		}
307
	}
308
}
(1-1/2)