Project

General

Profile

1
package eu.dnetlib.enabling.is.lookup;
2

    
3
import java.io.IOException;
4
import java.io.StringReader;
5
import java.util.ArrayList;
6
import java.util.List;
7
import java.util.regex.Matcher;
8
import java.util.regex.Pattern;
9
import javax.jws.WebService;
10
import javax.xml.parsers.ParserConfigurationException;
11
import javax.xml.xpath.XPathExpressionException;
12

    
13
import com.sun.xml.messaging.saaj.util.Base64;
14
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
15
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
16
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
17
import eu.dnetlib.enabling.is.store.rmi.ISStoreException;
18
import eu.dnetlib.enabling.is.store.rmi.ISStoreService;
19
import eu.dnetlib.enabling.tools.*;
20
import org.apache.commons.lang3.StringUtils;
21
import org.apache.commons.logging.Log;
22
import org.apache.commons.logging.LogFactory;
23
import org.dom4j.Document;
24
import org.dom4j.Element;
25
import org.dom4j.io.SAXReader;
26
import org.springframework.beans.factory.annotation.Required;
27
import org.xml.sax.SAXException;
28

    
29
/**
30
 * ISLookUpService implementation.
31
 * 
32
 * @author marko
33
 * @author michele
34
 * 
35
 */
36
@WebService(targetNamespace = "http://services.dnetlib.eu/")
37
public class ISLookUpServiceImpl extends AbstractBaseService implements ISLookUpService { // NOPMD
38

    
39
	/**
40
	 * error message when the given collection cannot be fetched.
41
	 */
42
	private static final String COLLECTION_ERROR = "cannot get collection";
43

    
44
	/**
45
	 * base xmldb directory.
46
	 */
47
	private static final String DB_BASE_DIR = "/db/DRIVER";
48

    
49
	/**
50
	 * error message when the profile is not present in the db.
51
	 */
52
	private static final String PROFILE_NOT_FOUND = "Profile not found";
53

    
54
	private ISStoreService isStore;
55

    
56
	// NOPMD by marko on 11/24/08
57
	// 5:02 PM
58
	/**
59
	 * logger.
60
	 */
61
	public static final Log log = LogFactory.getLog(ISLookUpServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
62

    
63
	/**
64
	 * resource identifier resolver. Resolves identifiers to xmldb file and collection names.
65
	 */
66
	private ResourceIdentifierResolver resIdManager = new CompatResourceIdentifierResolverImpl();
67

    
68
	/**
69
	 * xquery utils. Used to obtain the xmldb collection mapping for resources.
70
	 */
71
	private XQueryUtils xqueryUtils;
72

    
73
	/**
74
	 * {@inheritDoc}
75
	 * 
76
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#flushCachedResultSets()
77
	 */
78
	@Override
79
	public Boolean flushCachedResultSets() {
80
		// TODO Auto-generated method stub
81
		return false;
82
	}
83

    
84
	/**
85
	 * {@inheritDoc}
86
	 * 
87
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#retrieveCollection(java.lang.String)
88
	 */
89
	@Override
90
	public String retrieveCollection(final String profId) throws ISLookUpException {
91
		try {
92
			String profile = this.getResourceProfile(profId);
93
			final List<String> list = quickSearchProfile("for $x in collection('/db/DRIVER/CollectionDSResources') where $x//FATHER/@id = '" + profId
94
					+ "' return $x//RESOURCE_IDENTIFIER/@value/string()");
95

    
96
			if (!list.isEmpty()) {
97
				final SAXReader reader = new SAXReader();
98
				final Document doc = reader.read(new StringReader(profile));
99
				final Element childrenNode = (Element) doc.selectSingleNode("//CHILDREN"); // NOPMD
100
				for (final String idC : list) {
101
					childrenNode.addElement("CHILD").addAttribute("id", idC);
102
				}
103
				profile = doc.asXML();
104
			}
105

    
106
			return profile;
107
		} catch (final Exception e) {
108
			throw new ISLookUpException(e);
109
		}
110
	}
111

    
112
	/**
113
	 * {@inheritDoc}
114
	 * 
115
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getCollection(java.lang.String, java.lang.String)
116
	 */
117
	@Override
118
	public String getCollection(final String profId, final String format) throws ISLookUpException {
119
		OpaqueResource prof;
120
		try {
121
			prof = new StringOpaqueResource(profId);
122

    
123
			final StringBuilder query = new StringBuilder();
124
			if (format != null && format.equals("ui")) {
125
				query.append("doc('");
126
				query.append(xqueryUtils.getCollectionAbsPath(prof));
127
				query.append('/');
128
				query.append(prof.getResourceId().split("_")[0]);
129
				query.append("')");
130
			} else {
131
				query.append("let $x := doc('");
132
				query.append(xqueryUtils.getCollectionAbsPath(prof));
133
				query.append('/');
134
				query.append(prof.getResourceId().split("_")[0]);
135
				query.append("') return <COLLECTION name='{$x//NAME}' id='{$x//RESOURCE_IDENTIFIER/@value/string()}'>");
136
				query.append("<STATUS private='{$x//PRIVATE}' visible='{$x//VISIBLE}' container='{$x//CONTAINER}'");
137
				query.append("count_docs='{$x//COUNT_DOCS/@number/string()}' last_update='{$x//COUNT_DOCS/@last_update/string()}' />");
138
				query.append("{$x//IMAGE_URL}{$x//DESCRIPTION}{$x//OWNER}{$x//FATHER}{$x//SUBJECT}{$x//CHILDREN}{$x//MEMBERSHIP_CONDITION}{$x//RETRIEVAL_CONDITION}</COLLECTION>");
139
			}
140

    
141
			return isStore.getXMLbyQuery(query.toString());
142
		} catch (final ISStoreException e) {
143
			throw new ISLookUpException(e);
144
		} catch (final XPathExpressionException e) {
145
			throw new ISLookUpException(COLLECTION_ERROR, e);
146
		} catch (final SAXException e) {
147
			throw new ISLookUpException(COLLECTION_ERROR, e);
148
		} catch (final IOException e) {
149
			throw new ISLookUpException(COLLECTION_ERROR, e);
150
		} catch (final ParserConfigurationException e) {
151
			throw new ISLookUpException(COLLECTION_ERROR, e);
152
		}
153
	}
154

    
155
	/**
156
	 * {@inheritDoc}
157
	 * 
158
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceProfile(java.lang.String)
159
	 */
160
	@Override
161
	public String getResourceProfile(final String profId) throws ISLookUpException {
162
		if (profId == null || profId.isEmpty()) { throw new ISLookUpException("Invalid null profile ID: " + profId); }
163

    
164
		try {
165
			final String res = isStore.getXML(getFileNameForId(profId),
166
					xqueryUtils.getRootCollection() + getFileCollForId(profId));
167
			if (res == null) { throw new ISLookUpDocumentNotFoundException("document " + profId + " not found"); }
168
			return res;
169
		} catch (final ISStoreException e) {
170
			throw new ISLookUpException(e);
171
		}
172
	}
173

    
174
	/**
175
	 * obtain the xmldb file name from the profile identifier.
176
	 * 
177
	 * @param profId
178
	 *            profile id
179
	 * @return xml db file name
180
	 */
181
	String getFileNameForId(final String profId) {
182
		return resIdManager.getFileName(profId);
183
	}
184

    
185
	/**
186
	 * obtain the xmldb collection name from the profile identifier.
187
	 * 
188
	 * @param profId
189
	 *            profile id
190
	 * @return plaintext xmldb collection name
191
	 */
192
	String getFileCollForId(final String profId) {
193
		return resIdManager.getCollectionName(profId);
194
	}
195

    
196
	/**
197
	 * {@inheritDoc}
198
	 * 
199
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceProfileByQuery(java.lang.String)
200
	 */
201
	@Override
202
	public String getResourceProfileByQuery(final String xquery) throws ISLookUpException {
203
		String resource;
204
		//TODO remove following hack as soon as https://issue.openaire.research-infrastructures.eu/issues/2774 is closed.
205
		if (StringUtils.isNotBlank(xquery) && xquery.trim().startsWith("//*[local-name() = 'complexType'")) {
206
			final Pattern p = Pattern.compile(".*value = '([a-zA-z]+)']");
207
			final Matcher m = p.matcher(xquery);
208
			if (m.matches()) {
209
				final String serviceName = m.group(1);
210
				log.debug(String.format("found service '%s', hacking response for xquery: %s", serviceName, xquery));
211
				return getResourceTypeSchema(serviceName);
212
			}
213
		}
214
		try {
215
			resource = isStore.getXMLbyQuery(xquery);
216
			if (resource == null || resource.isEmpty()) { throw new ISLookUpDocumentNotFoundException(PROFILE_NOT_FOUND); }
217
			return resource;
218
		} catch (final ISStoreException e) {
219
			throw new ISLookUpException(e);
220
		}
221
	}
222

    
223
	/**
224
	 * {@inheritDoc}
225
	 * 
226
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceQoSParams(java.lang.String)
227
	 */
228
	@Override
229
	public String getResourceQoSParams(final String profId) throws ISLookUpException {
230
		final String query = "for $x in collection('/db/DRIVER/ServiceResources') where $x//RESOURCE_IDENTIFIER/@value = '" + profId + "' return $x//QOS";
231
		return getResourceProfileByQuery(query);
232
	}
233

    
234
	/**
235
	 * {@inheritDoc}
236
	 * 
237
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#getResourceTypeSchema(java.lang.String)
238
	 */
239
	@Override
240
	public String getResourceTypeSchema(final String resourceType) throws ISLookUpException, ISLookUpDocumentNotFoundException {
241
		if (resourceType == null || resourceType.isEmpty()) { throw new ISLookUpException("Invalid resourceType"); }
242

    
243
		try {
244
			final String resource = isStore.getXML(resourceType, xqueryUtils.getRootCollection() + ResourceType.RESOURCE_TYPES);
245
			if (resource == null || resource.isEmpty()) { throw new ISLookUpDocumentNotFoundException(PROFILE_NOT_FOUND); }
246
			return resource;
247
		} catch (final ISStoreException e) {
248
			throw new ISLookUpException(e);
249
		}
250
	}
251

    
252
	/**
253
	 * {@inheritDoc}
254
	 * 
255
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listCollections(java.lang.String, java.lang.String, java.lang.String)
256
	 */
257
	@Override
258
	public List<String> listCollections(final String format, final String idfatherParam, final String owner) throws ISLookUpException {
259
		String idfather = idfatherParam; // PMD
260
		if (idfather == null || idfather.length() == 0) {
261
			idfather = "InfoSpace";
262
		}
263
		final String fileColl = xqueryUtils.getRootCollection() + "CollectionDSResources/CollectionDSResourceType";
264

    
265
		final StringBuilder query = new StringBuilder();
266
		query.append("for $x in collection('" + fileColl + "') where $x//FATHER[@id='" + idfather + "'] "); // NOPMD
267
		if (owner != null && owner.length() > 0) {
268
			query.append("and $x//OWNER[@id='" + owner + "'] ");
269
		}
270
		if (format != null && format.equals("short")) {
271
			query.append("return $x//RESOURCE_IDENTIFIER/@value/string()");
272
		} else {
273
			query.append("return $x");
274
		}
275

    
276
		return quickSearchProfile(query.toString());
277
	}
278

    
279
	/**
280
	 * {@inheritDoc}
281
	 * 
282
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listDHNIDs()
283
	 */
284
	@Override
285
	public List<String> listDHNIDs() throws ISLookUpException {
286
		final String fileColl = DB_BASE_DIR + "/InfrastructureResources/DRIVERHostingNodeDSResourceType";
287

    
288
		final ArrayList<String> ret = new ArrayList<String>();
289
		try {
290
			for (final String i : isStore.getFileNames(fileColl)) {
291
				ret.add(i + ":" + fileColl);
292
			}
293
			return ret;
294
		} catch (final ISStoreException e) {
295
			throw new ISLookUpException(e);
296
		}
297
	}
298

    
299
	/**
300
	 * {@inheritDoc}
301
	 * 
302
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listResourceTypes()
303
	 */
304
	@Override
305
	public List<String> listResourceTypes() throws ISLookUpException {
306
		try {
307
			return isStore.getFileNames(DB_BASE_DIR + "/" + ResourceType.RESOURCE_TYPES);
308
		} catch (final ISStoreException e) {
309
			throw new ISLookUpException(e);
310
		}
311
	}
312

    
313
	/**
314
	 * {@inheritDoc}
315
	 * 
316
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listServiceIDs(java.lang.String)
317
	 */
318
	@Override
319
	public List<String> listServiceIDs(final String serviceType) throws ISLookUpException {
320
		final String fileColl = "ServiceResources/" + serviceType;
321
		final String encodedColl = "_" + new String(Base64.encode(fileColl.getBytes())); // NOPMD
322

    
323
		final List<String> ret = new ArrayList<String>();
324
		try {
325
			for (final String i : isStore.getFileNames(DB_BASE_DIR + "/" + fileColl)) {
326
				ret.add(i + encodedColl);
327
			}
328
			return ret;
329
		} catch (final ISStoreException e) {
330
			throw new ISLookUpException(e);
331
		}
332
	}
333

    
334
	/**
335
	 * {@inheritDoc}
336
	 * 
337
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#listServiceTypes()
338
	 */
339
	@Override
340
	public List<String> listServiceTypes() throws ISLookUpException {
341
		final List<String> ret = new ArrayList<String>();
342
		try {
343
			for (final String i : isStore.getFileColls()) {
344
				if (i.startsWith("ServiceResources/")) {
345
					ret.add(i.substring("ServiceResources/".length()));
346
				}
347
			}
348
			return ret;
349
		} catch (final ISStoreException e) {
350
			throw new ISLookUpException(e);
351
		}
352
	}
353

    
354
	/**
355
	 * {@inheritDoc}
356
	 * 
357
	 * @see eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService#quickSearchProfile(java.lang.String)
358
	 */
359
	@Override
360
	public List<String> quickSearchProfile(final String xquery) throws ISLookUpException {
361
		try {
362
			return isStore.quickSearchXML(xquery);
363
		} catch (final ISStoreException e) {
364
			throw new ISLookUpException(e);
365
		}
366
	}
367

    
368
	public ResourceIdentifierResolver getResIdManager() {
369
		return resIdManager;
370
	}
371

    
372
	public void setResIdManager(final ResourceIdentifierResolver resIdManager) {
373
		this.resIdManager = resIdManager;
374
	}
375

    
376
	@Required
377
	public void setXqueryUtils(final XQueryUtils xqueryUtils) {
378
		this.xqueryUtils = xqueryUtils;
379
	}
380

    
381
	public XQueryUtils getXqueryUtils() {
382
		return xqueryUtils;
383
	}
384

    
385
	public ISStoreService getIsStore() {
386
		return isStore;
387
	}
388

    
389
	@Required
390
	public void setIsStore(final ISStoreService isStore) {
391
		this.isStore = isStore;
392
	}
393

    
394
}
    (1-1/1)