Project

General

Profile

1
package eu.dnetlib.clients.index.model.document;
2

    
3
import java.util.*;
4

    
5
import eu.dnetlib.clients.index.model.Any.ValueType;
6
import eu.dnetlib.clients.index.utils.IndexFieldUtility;
7

    
8
/**
9
 * The Class AbstractDocument Represent the field information needed to construct and index Document.
10
 */
11
public abstract class AbstractIndexDocument implements Map<String, IndexField>, Iterable<IndexField>, IndexDocument {
12

    
13
	private static final String DATE_SUFFIX = "\\+\\d{2}:\\d{2}";
14
	/**
15
	 * The _fields.
16
	 */
17
	protected final Map<String, IndexField> fields;
18
	/**
19
	 * index schema.
20
	 */
21
	protected final Map<String, ValueType> schema;
22
	/**
23
	 * Actual document status.
24
	 */
25
	private Status status;
26
	/**
27
	 * If there was an error building the document, it is described here.
28
	 */
29
	private Throwable error;
30

    
31
	/**
32
	 * Instantiates a new abstract document.
33
	 */
34
	public AbstractIndexDocument(final Map<String, ValueType> schema, final String dsId) {
35
		this.schema = schema;
36
		fields = new LinkedHashMap<>();
37
	}
38

    
39
	/**
40
	 * Instantiates a new abstract document.
41
	 *
42
	 * @param fields the fields
43
	 */
44
	public AbstractIndexDocument(final Map<String, ValueType> schema, final String dsId, final Map<String, IndexField> fields) {
45
		this.schema = schema;
46
		this.fields = fields;
47
		addField(IndexFieldUtility.DS_ID, dsId);
48
	}
49

    
50
	/**
51
	 * Remove all fields and boosts from the document.
52
	 */
53
	@Override
54
	public void clear() {
55
		if (fields != null) {
56
			fields.clear();
57
		}
58
	}
59

    
60
	/**
61
	 * {@inheritDoc}
62
	 */
63
	@Override
64
	public void addField(final String name, final Object value) {
65
		Object hack_value = hackField(name, value);
66
		IndexField field = fields.get(name);
67
		if ((field == null) || (field.getValue() == null)) {
68
			setField(name, hack_value);
69
		} else {
70
			field.addValue(hack_value);
71
		}
72
	}
73

    
74
	/**
75
	 * {@inheritDoc}
76
	 */
77
	@Override
78
	public Object getFieldValue(final String name) {
79
		IndexField field = getField(name);
80
		Object o = null;
81
		if (field != null) {
82
			o = field.getFirstValue();
83
		}
84
		return o;
85
	}
86

    
87
	/**
88
	 * {@inheritDoc}
89
	 */
90
	@Override
91
	public IndexField getField(final String field) {
92
		return fields.get(field);
93
	}
94

    
95
	/**
96
	 * {@inheritDoc}
97
	 */
98
	@Override
99
	public Collection<Object> getFieldValues(final String name) {
100
		IndexField field = getField(name);
101
		if (field != null) return field.getValues();
102
		return null;
103
	}
104

    
105
	/**
106
	 * {@inheritDoc}
107
	 */
108
	@Override
109
	public Collection<String> getFieldNames() {
110
		return fields.keySet();
111
	}
112

    
113
	/**
114
	 * {@inheritDoc}
115
	 */
116
	@Override
117
	public void setField(final String name, final Object value) {
118
		Object hack_value = hackField(name, value);
119
		IndexField field = new IndexField(name);
120
		fields.put(name, field);
121
		field.setValue(hack_value);
122
	}
123

    
124
	/**
125
	 * {@inheritDoc}
126
	 */
127
	@Override
128
	public IndexField removeField(final String name) {
129
		return fields.remove(name);
130
	}
131

    
132
	/**
133
	 * {@inheritDoc}
134
	 *
135
	 * @see Iterable#iterator()
136
	 */
137
	@Override
138
	public Iterator<IndexField> iterator() {
139
		return fields.values().iterator();
140
	}
141

    
142
	/**
143
	 * {@inheritDoc}
144
	 *
145
	 * @see Object#toString()
146
	 */
147
	@Override
148
	public String toString() {
149
		return "IndexDocument: " + fields.values();
150
	}
151

    
152
	// ---------------------------------------------------
153
	// MAP interface
154
	// ---------------------------------------------------
155

    
156
	/**
157
	 * {@inheritDoc}
158
	 *
159
	 * @see Map#containsKey(Object)
160
	 */
161
	@Override
162
	public boolean containsKey(final Object key) {
163
		return fields.containsKey(key);
164
	}
165

    
166
	/**
167
	 * {@inheritDoc}
168
	 *
169
	 * @see Map#containsValue(Object)
170
	 */
171
	@Override
172
	public boolean containsValue(final Object value) {
173
		return fields.containsValue(value);
174
	}
175

    
176
	/**
177
	 * {@inheritDoc}
178
	 *
179
	 * @see Map#entrySet()
180
	 */
181
	@Override
182
	public Set<Entry<String, IndexField>> entrySet() {
183
		return fields.entrySet();
184
	}
185

    
186
	/**
187
	 * {@inheritDoc}
188
	 *
189
	 * @see Map#get(Object)
190
	 */
191
	@Override
192
	public IndexField get(final Object key) {
193
		return fields.get(key);
194
	}
195

    
196
	/**
197
	 * {@inheritDoc}
198
	 *
199
	 * @see Map#isEmpty()
200
	 */
201
	@Override
202
	public boolean isEmpty() {
203
		return fields.isEmpty();
204
	}
205

    
206
	/**
207
	 * {@inheritDoc}
208
	 *
209
	 * @see Map#keySet()
210
	 */
211
	@Override
212
	public Set<String> keySet() {
213
		return fields.keySet();
214
	}
215

    
216
	/**
217
	 * {@inheritDoc}
218
	 *
219
	 * @see Map#put(Object, Object)
220
	 */
221
	@Override
222
	public IndexField put(final String key, final IndexField value) {
223
		return fields.put(key, value);
224
	}
225

    
226
	/**
227
	 * {@inheritDoc}
228
	 *
229
	 * @see Map#putAll(Map)
230
	 */
231
	@Override
232
	public void putAll(final Map<? extends String, ? extends IndexField> t) {
233
		fields.putAll(t);
234
	}
235

    
236
	/**
237
	 * {@inheritDoc}
238
	 *
239
	 * @see Map#remove(Object)
240
	 */
241
	@Override
242
	public IndexField remove(final Object key) {
243
		return fields.remove(key);
244
	}
245

    
246
	/**
247
	 * {@inheritDoc}
248
	 *
249
	 * @see Map#size()
250
	 */
251
	@Override
252
	public int size() {
253
		return fields.size();
254
	}
255

    
256
	/**
257
	 * {@inheritDoc}
258
	 *
259
	 * @see Map#values()
260
	 */
261
	@Override
262
	public Collection<IndexField> values() {
263
		return fields.values();
264
	}
265

    
266
	/**
267
	 * {@inheritDoc}
268
	 */
269
	@Override
270
	public Status getStatus() {
271
		return status;
272
	}
273

    
274
	/**
275
	 * Sets the status.
276
	 *
277
	 * @param status the status to set
278
	 * @return the index document
279
	 */
280
	@Override
281
	public IndexDocument setStatus(final Status status) {
282
		this.status = status;
283
		return this;
284
	}
285

    
286
	/**
287
	 * {@inheritDoc}
288
	 */
289
	@Override
290
	public IndexDocument deepCopy() {
291
		// TODO Auto-generated method stub
292
		return null;
293
	}
294

    
295
	/**
296
	 * {@inheritDoc}
297
	 */
298
	@Override
299
	public Throwable getError() {
300

    
301
		return error;
302
	}
303

    
304
	/**
305
	 * {@inheritDoc}
306
	 */
307
	@Override
308
	public IndexDocument setOK() {
309

    
310
		return this.setStatus(Status.OK);
311
	}
312

    
313
	/**
314
	 * {@inheritDoc}
315
	 */
316
	@Override
317
	public IndexDocument setMarked() {
318
		addField(IndexFieldUtility.DELETE_DOCUMENT, true);
319
		return this.setStatus(Status.MARKED);
320
	}
321

    
322
	/**
323
	 * {@inheritDoc}
324
	 */
325
	@Override
326
	public IndexDocument setError(final Throwable error) {
327
		this.error = error;
328
		return this.setStatus(Status.ERROR);
329
	}
330

    
331
	/**
332
	 * This method modifies a field w.r.t. his type
333
	 *
334
	 * @param name
335
	 * @param value
336
	 * @return
337
	 */
338
	private Object hackField(final String name, Object value) {
339
		if (schema == null) return value;
340

    
341
		final ValueType type = schema.get(name);
342

    
343
		// TODO: hack this is hardcoded for the date type
344
		switch (type) {
345
		case DATETIME:
346
		case DATE:
347
			if (value.toString().matches(DATE_SUFFIX)) return value.toString().replaceAll(DATE_SUFFIX, "Z");
348
			if (value.toString().endsWith("Z")) return value;
349

    
350
			value = value + "T00:00:00Z";
351
			break;
352
		default:
353
			break;
354
		}
355
		return value;
356
	}
357

    
358
}
(1-1/4)