Project

General

Profile

« Previous | Next » 

Revision 26968

migrated from dnet30

View differences:

modules/cnr-index-inspector/trunk/src/main/java/eu/dnetlib/data/index/inspector/IndexInspector.java
1
package eu.dnetlib.data.index.inspector;
2

  
3
import java.io.UnsupportedEncodingException;
4
import java.net.URLEncoder;
5
import java.util.ArrayList;
6
import java.util.List;
7
import java.util.Set;
8

  
9
import javax.annotation.Resource;
10
import javax.xml.ws.wsaddressing.W3CEndpointReference;
11

  
12
import org.apache.commons.logging.Log;
13
import org.apache.commons.logging.LogFactory;
14
import org.springframework.stereotype.Controller;
15
import org.springframework.ui.Model;
16
import org.springframework.web.bind.annotation.RequestMapping;
17
import org.springframework.web.bind.annotation.RequestParam;
18

  
19
import com.google.common.collect.Lists;
20
import com.google.common.collect.Sets;
21

  
22
import eu.dnetlib.data.index.IIndexService;
23
import eu.dnetlib.data.index.IndexServiceException;
24
import eu.dnetlib.enabling.inspector.AbstractInspectorController;
25
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
26
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
27
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
28
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
29
import eu.dnetlib.enabling.tools.ServiceEnumerator;
30
import eu.dnetlib.enabling.tools.ServiceLocator;
31
import eu.dnetlib.enabling.tools.ServiceResolver;
32
import eu.dnetlib.enabling.tools.ServiceRunningInstance;
33
import eu.dnetlib.miscutils.collections.MappedCollection;
34
import eu.dnetlib.miscutils.datetime.HumanTime;
35
import eu.dnetlib.miscutils.functional.UnaryFunction;
36
import eu.dnetlib.miscutils.functional.string.EscapeHtml;
37
import eu.dnetlib.miscutils.functional.xml.IndentXmlString;
38
import eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder;
39

  
40
/**
41
 * Allows to perform queries to indices.
42
 * 
43
 * @author marko
44
 * 
45
 */
46
@Controller
47
public class IndexInspector extends AbstractInspectorController {
48

  
49
	public static class SelectOption {
50
		private String value;
51
		private boolean selected;
52

  
53
		public SelectOption(final String value, final boolean selected) {
54
			super();
55
			this.value = value;
56
			this.selected = selected;
57
		}
58

  
59
		public String getValue() {
60
			return value;
61
		}
62

  
63
		public void setValue(final String value) {
64
			this.value = value;
65
		}
66

  
67
		public boolean isSelected() {
68
			return selected;
69
		}
70

  
71
		public void setSelected(final boolean selected) {
72
			this.selected = selected;
73
		}
74

  
75
	}
76

  
77
	/**
78
	 * result page size.
79
	 */
80
	private static final int PAGE_SIZE = 10;
81

  
82
	/**
83
	 * logger.
84
	 */
85
	private static final Log log = LogFactory.getLog(IndexInspector.class); // NOPMD by marko on 11/24/08 5:02 PM
86

  
87
	/**
88
	 * index service locator.
89
	 */
90
	@Resource(name = "anyIndexLocator")
91
	private ServiceLocator<IIndexService> indexLocator;
92

  
93
	/**
94
	 * lookup locator.
95
	 */
96
	@Resource(name = "lookupLocator")
97
	private ServiceLocator<ISLookUpService> lookupLocator;
98

  
99
	/**
100
	 * service resolver.
101
	 */
102
	@Resource
103
	private ServiceResolver serviceResolver;
104

  
105
	/**
106
	 * index service enumerator.
107
	 */
108
	@Resource(name = "indexServiceEnumerator")
109
	private ServiceEnumerator<IIndexService> indexEnumerator;
110
	
111
	/**
112
	 * epr builder.
113
	 */
114
	@Resource
115
	private CxfEndpointReferenceBuilder eprBuilder;
116
	
117
	/**
118
	 * local index service URL
119
	 */
120
	@Resource
121
	private String localIndexServiceUrl;
122

  
123
	/**
124
	 * search the whole index service.
125
	 * 
126
	 * @param model
127
	 *            mvc model
128
	 * @param query
129
	 *            query
130
	 * @param format
131
	 *            metadata format
132
	 * @throws IndexServiceException
133
	 *             could happen
134
	 * @throws ResultSetException
135
	 *             could happen
136
	 * @throws ISLookUpException
137
	 *             could happen
138
	 */
139
	@RequestMapping(value = "/inspector/searchIndex.do")
140
	public void search(
141
			final Model model,
142
			@RequestParam(value = "query", required = false) final String query,
143
			@RequestParam(value = "format", required = false) final String format,
144
			@RequestParam(value = "layout", required = false) final String layout,
145
			@RequestParam(value = "indexService", required = false) final String indexServiceUrl,
146
			@RequestParam(value = "indent", required = false) final Boolean indent) 
147
		throws IndexServiceException, ResultSetException, ISLookUpException {
148

  
149
		final List<ServiceRunningInstance<IIndexService>> indexServices = indexEnumerator.getServices();
150
		
151
		if (query != null) {
152
			log.info("running query: " + query + " on format " + format + " with layout " + layout);
153

  
154
			final W3CEndpointReference indexEpr;
155
			
156
			if(indexServiceUrl == null || "".equals(indexServiceUrl)) 
157
				indexEpr = indexServices.get(0).getEpr();
158
			else 
159
				indexEpr = eprBuilder.getEndpointReference(indexServiceUrl, null, null, null, null, null);
160
			
161
			final IIndexService indexService = serviceResolver.getService(IIndexService.class, indexEpr);
162

  
163
			final W3CEndpointReference epr = indexService.indexLookup("all", query, format, layout);
164

  
165
			log.info("GOT EPR: " + epr);
166

  
167
			final ResultSetService resultSet = serviceResolver.getService(ResultSetService.class, epr);
168
			final String rsId = serviceResolver.getResourceIdentifier(epr);
169

  
170
			final int total = resultSet.getNumberOfElements(rsId);
171
			int pageSize = PAGE_SIZE;
172
			if (total < pageSize)
173
				pageSize = total;
174

  
175
			List<String> elements = resultSet.getResult(rsId, 1, pageSize, "waiting");
176
			if (elements == null)
177
				elements = new ArrayList<String>();
178
			
179
			if (indent != null && indent)
180
				elements = MappedCollection.listMap(elements, new IndentXmlString());
181
			
182
			final List<String> escaped = MappedCollection.listMap(elements, new EscapeHtml());
183
			model.addAttribute("indent", indent);
184
			model.addAttribute("size", total);
185
			model.addAttribute("results", escaped);
186
		}
187

  
188
		final List<String> formats = lookupLocator.getService().quickSearchProfile(
189
				"distinct-values(//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'IndexDSResourceType']//METADATA_FORMAT/text())");
190

  
191
		final List<String> layouts = lookupLocator.getService().quickSearchProfile(
192
				"distinct-values(for $x in //RESOURCE_PROFILE//LAYOUT/@name/string() order by $x return $x)");
193

  
194
		Set<String> indices = Sets.newHashSet();
195
		for (ServiceRunningInstance<IIndexService> index : indexServices) {
196
			indices.add(index.getUrl());
197
		}
198
		
199
		indices.add(localIndexServiceUrl);
200

  
201
		model.addAttribute("indexServices", selectOptions(Lists.newArrayList(indices), indexServiceUrl));
202

  
203
		model.addAttribute("formats", selectOptions(formats, format));
204
		model.addAttribute("layouts", selectOptions(layouts, layout));
205

  
206
		model.addAttribute("query", query);
207
	}
208

  
209
	@RequestMapping(value = "/inspector/browseIndex.do")
210
	public void browse(
211
			final Model model,
212
			@RequestParam(value = "query", required = false) String querySource,
213
			@RequestParam(value = "field", required = false) final String browseField,
214
			@RequestParam(value = "idxId", required = false) final String idxId,
215
			@RequestParam(value = "indexService", required = false) final String indexServiceUrl,			
216
			@RequestParam(value = "format", required = false) final String format,
217
			@RequestParam(value = "layout", required = false) final String layout,
218
			@RequestParam(value = "start", required = false) Integer startParam,
219
			@RequestParam(value = "indent", required = false) final Boolean indent) 
220
		throws IndexServiceException, ResultSetException, ISLookUpException, UnsupportedEncodingException {
221

  
222
		long starting = System.currentTimeMillis();
223
		long elapsed = starting;
224
		int total = 0;
225
		int start = 0;
226
		int pageSize = PAGE_SIZE;
227
		
228
		final List<ServiceRunningInstance<IIndexService>> indexServices = indexEnumerator.getServices();
229

  
230
		if (startParam != null)
231
			start = startParam;
232
		
233
		if (browseField != null) {
234
			log.info("browsing field: " + browseField + " on format " + format + " with layout " + layout);
235

  
236
			String query = "query=" + querySource + "&groupby=" + browseField;
237
			
238
			final W3CEndpointReference indexEpr;
239
			
240
			if(indexServiceUrl == null || "".equals(indexServiceUrl)) 
241
				indexEpr = indexServices.get(0).getEpr();
242
			else 
243
				indexEpr = eprBuilder.getEndpointReference(indexServiceUrl, null, null, null, null, null);			
244
						
245
			final IIndexService indexService = serviceResolver.getService(IIndexService.class, indexEpr);
246
			
247
			final W3CEndpointReference epr = indexService.getBrowsingStatistics(query, idxId, format, layout);
248

  
249
			log.debug("GOT EPR: " + epr);
250

  
251
			final ResultSetService resultSet = serviceResolver.getService(ResultSetService.class, epr);
252
			final String rsId = serviceResolver.getResourceIdentifier(epr);
253

  
254
			total = resultSet.getNumberOfElements(rsId);
255
			if (total < pageSize)
256
				pageSize = total;
257

  
258
			List<String> elements = resultSet.getResult(rsId, 1 + start, start + pageSize, "waiting");
259
			if (elements == null)
260
				elements = new ArrayList<String>();
261
			
262
			if (indent != null && indent)
263
				elements = MappedCollection.listMap(elements, new IndentXmlString());
264
			
265
			final List<String> escaped = MappedCollection.listMap(elements, new EscapeHtml());
266
			
267
			elapsed = System.currentTimeMillis() - starting;
268
			
269
			model.addAttribute("results", escaped);
270
			model.addAttribute("elapsed", HumanTime.exactly(elapsed));
271
		}		
272
		
273
		final List<String> fields  = lookupLocator.getService().quickSearchProfile(
274
				"distinct-values(//RESOURCE_PROFILE//LAYOUT//FIELD/@browsingAliasFor/string())");
275
		final List<String> formats = lookupLocator.getService().quickSearchProfile(
276
				"distinct-values(//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'IndexDSResourceType']//METADATA_FORMAT/text())");
277
		final List<String> layouts = lookupLocator.getService().quickSearchProfile(
278
				"distinct-values(for $x in //RESOURCE_PROFILE//LAYOUT/@name/string() order by $x return $x)");
279
		final List<String> idxIds  = lookupLocator.getService().quickSearchProfile(
280
				"//RESOURCE_IDENTIFIER[../RESOURCE_TYPE/@value = 'IndexDSResourceType']/@value/string()");
281
		
282
		idxIds.add(0, "all");
283
		
284
		Set<String> indices = Sets.newHashSet();
285
		for (ServiceRunningInstance<IIndexService> index : indexServices) {
286
			indices.add(index.getUrl());
287
		}
288
		
289
		indices.add(localIndexServiceUrl);		
290
		
291
		if(querySource == null || querySource.equals(""))
292
			querySource = "textual";
293
	
294
		model.addAttribute("indexServices", selectOptions(Lists.newArrayList(indices), indexServiceUrl));
295
		model.addAttribute("encodedQuerySource", URLEncoder.encode(querySource, "UTF-8"));
296
		model.addAttribute("querySource", querySource);
297
		model.addAttribute("total", total);
298
		model.addAttribute("start", start);
299
		model.addAttribute("nextPage", start + pageSize);
300
		model.addAttribute("prevPage", Math.max(0, start - pageSize));
301
		model.addAttribute("indent", indent);
302
		
303
		model.addAttribute("browseField", browseField);
304
		
305
		model.addAttribute("fields", selectOptions(fields, browseField));
306
		model.addAttribute("idxIds", selectOptions(idxIds, idxId));
307
		model.addAttribute("formats", selectOptions(formats, format));
308
		model.addAttribute("layouts", selectOptions(layouts, layout));
309

  
310
	}
311

  
312
	/**
313
	 * Given an list of values, return a list of SelectOption instances which have the "selected" boolean field set to
314
	 * true only for the element matching "current".
315
	 * 
316
	 * @param input
317
	 *            list of input strings
318
	 * @param current
319
	 *            current value to select
320
	 * @return
321
	 */
322
	private List<SelectOption> selectOptions(final List<String> input, final String current) {
323
		return MappedCollection.listMap(input, new UnaryFunction<SelectOption, String>() {
324
			@Override
325
			public SelectOption evaluate(final String value) {
326
				return new SelectOption(value, value.equals(current));
327
			}
328
		});
329
	}
330

  
331
	public ServiceLocator<IIndexService> getIndexLocator() {
332
		return indexLocator;
333
	}
334

  
335
	public void setIndexLocator(final ServiceLocator<IIndexService> indexLocator) {
336
		this.indexLocator = indexLocator;
337
	}
338

  
339
	public ServiceResolver getServiceResolver() {
340
		return serviceResolver;
341
	}
342

  
343
	public void setServiceResolver(final ServiceResolver serviceResolver) {
344
		this.serviceResolver = serviceResolver;
345
	}
346

  
347
	public ServiceLocator<ISLookUpService> getLookupLocator() {
348
		return lookupLocator;
349
	}
350

  
351
	public void setLookupLocator(final ServiceLocator<ISLookUpService> lookupLocator) {
352
		this.lookupLocator = lookupLocator;
353
	}
354
}
modules/cnr-index-inspector/trunk/src/main/resources/eu/dnetlib/enabling/views/inspector/searchIndex.st
1
$inspector/master(it={
2

  
3
<style type="text/css">
4
  #results {
5
    width: 100%;
6
  }
7

  
8
  #results td:first-child {
9
   width: 2em;
10
  }
11

  
12
  #results td {
13
    border: 1px solid #cecece;
14
  }
15
</style>
16

  
17
<h2>Search indices</h2>
18

  
19
CQL query:
20

  
21
<form method="GET">
22
<textarea name="query" style="width: 880px; height: 120px" autofocus>$query$</textarea>
23
<br/>
24
<input type="submit" value="submit"/>
25
<select name="format">
26
 $formats:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
27
</select>
28
<select name="layout">
29
 $layouts:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
30
</select>
31
<select name="indexService">
32
 $indexServices:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
33
</select>
34
Indent? <input type="checkbox" name="indent" $if(indent)$checked="checked"$endif$/>
35
</form>
36

  
37
<p>$message$</p>
38

  
39
<p>$size$ results:</p>
40
<table id="results">
41
$results:{
42
<tr>
43
 <td><pre>$i$</pre></td>
44
 <td><pre>$it$</pre></td>
45
</tr>
46
}$
47
</table>
48

  
49
})$
modules/cnr-index-inspector/trunk/src/main/resources/eu/dnetlib/enabling/views/inspector/browseIndex.st
1
$inspector/master(it={
2

  
3
<style type="text/css">
4
  #results {
5
    width: 100%;
6
  }
7

  
8
  #results td:first-child {
9
   width: 2em;
10
  }
11

  
12
  #results td {
13
    border: 1px solid #cecece;
14
  }
15
</style>
16

  
17
<h2>Browse indices</h2>
18

  
19
<form method="GET">
20
CQL Query:<br/>
21
<textarea name="query" style="width: 640px; height: 40px" autofocus>$querySource$</textarea>
22
<br/>
23

  
24
Browse Fields:<br/>
25
<input name="field" value="$browseField$" size ="100%">
26
Indent? <input type="checkbox" name="indent" $if(indent)$checked="checked"$endif$/>
27

  
28
<br/>
29
<br/>
30
<input type="submit" value="submit"/>
31
<select name="format">
32
$formats:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
33
</select>
34

  
35
<select name="layout">
36
$layouts:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
37
</select>
38

  
39
<select name="indexService">
40
 $indexServices:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
41
</select>
42

  
43
<br/>
44

  
45
<select name="idxId">
46
$idxIds:{<option $if(it.selected)$selected$endif$>$it.value$</option>}$
47
</select>
48
&nbsp;&nbsp;&nbsp;
49
<br/>
50
<br/>
51
Elapsed time: $elapsed$
52
</form>
53

  
54
<p>$message$</p>
55

  
56
<p>Number of results: $total$ | Show from: $start$ 
57
(<a href="?query=$encodedQuerySource$&field=$browseField$&start=$prevPage$&indent=$indent$
58
	&idxId=$idxIds:{$if(it.selected)$$it.value$$endif$}$
59
	&format=$formats:{$if(it.selected)$$it.value$$endif$}$
60
	&layout=$layouts:{$if(it.selected)$$it.value$$endif$}$">prev</a>) 
61
out of $total$ 
62
(<a href="?query=$encodedQuerySource$&field=$browseField$&start=$nextPage$&indent=$indent$
63
	&idxId=$idxIds:{$if(it.selected)$$it.value$$endif$}$
64
	&format=$formats:{$if(it.selected)$$it.value$$endif$}$
65
	&layout=$layouts:{$if(it.selected)$$it.value$$endif$}$">next</a>)</p>
66

  
67
<table id="results">
68
$results:{
69
<tr>
70
 <td align="right"><pre>$i$</pre></td>
71
 <td><pre>$it$</pre></td>
72
</tr>
73
}$
74
</table>
75

  
76
})$
modules/cnr-index-inspector/trunk/src/main/resources/eu/dnetlib/data/index/inspector/applicationContext-index-inspector.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<beans xmlns="http://www.springframework.org/schema/beans"
3
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
4
	xmlns:context="http://www.springframework.org/schema/context"
5
	xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:lang="http://www.springframework.org/schema/lang"
6
	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
7
	xmlns:util="http://www.springframework.org/schema/util"
8
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
9
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
10
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
11
		http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
12
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
13
		http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
14
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
15

  
16
	<alias alias="anyIndexLocator" name="anyIndexLocatorDynamic" />
17

  
18
	<bean id="integrationBridgeIndexLocator" class="eu.dnetlib.enabling.tools.StaticServiceLocator"
19
		p:service-ref="anyIndexLocatorDynamic" />
20

  
21
	<bean id="indexServiceEnumerator" class="eu.dnetlib.enabling.tools.DynamicServiceEnumerator"
22
		p:eprBuilder-ref="cxfEndpointReferenceBuilder"
23
		p:serviceNameResolver-ref="defaultServiceNameResolver" p:clazz="eu.dnetlib.data.index.IIndexService"
24
		p:lookUpLocator-ref="lookupLocator" />
25
		
26
	<bean id="localIndexServiceUrl" class="java.lang.String">
27
		<constructor-arg value="http://${container.hostname}:${container.port}/${container.context}/services/IndexService"/>
28
	</bean>
29
	
30
	<bean id="anyIndexLocatorDynamic" class="eu.dnetlib.enabling.tools.DynamicServiceLocator"
31
		p:clazz="eu.dnetlib.data.index.IIndexService" p:lookUpLocator-ref="lookupLocator"
32
		p:serviceResolver-ref="serviceResolver" />	
33
	
34
</beans>
modules/cnr-index-inspector/trunk/src/main/resources/eu/dnetlib/data/index/inspector/webContext-index-inspector.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<beans xmlns="http://www.springframework.org/schema/beans"
3
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
	xmlns:p="http://www.springframework.org/schema/p"
5
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
6

  
7
	<bean id="indexInspectorGroup"
8
		class="eu.dnetlib.enabling.inspector.StaticEntryPointDescriptorGroup"
9
		p:name="index">
10
		<property name="descriptors">
11
			<list>
12
				<bean class="eu.dnetlib.enabling.inspector.StaticEntryPointDescriptor"
13
					p:name="cql" p:relativeUrl="searchIndex.do"/>
14
				<bean class="eu.dnetlib.enabling.inspector.StaticEntryPointDescriptor"
15
					p:name="browseIndex" p:relativeUrl="browseIndex.do"/>					
16
			</list>
17
		</property>
18
	</bean>
19

  
20
</beans>
modules/cnr-index-inspector/trunk/pom.xml
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4
	<parent>
5
		<groupId>eu.dnetlib</groupId>
6
		<artifactId>dnet-parent</artifactId>
7
		<version>0.0.1-SNAPSHOT</version>
8
	</parent>
9
	<modelVersion>4.0.0</modelVersion>
10
	<groupId>eu.dnetlib</groupId>
11
	<artifactId>cnr-index-inspector</artifactId>
12
	<packaging>jar</packaging>
13
	<version>0.0.10-SNAPSHOT</version>
14
	<dependencies>
15
		<dependency>
16
			<groupId>com.google.guava</groupId>
17
			<artifactId>guava</artifactId>
18
			<version>${google.guava.version}</version>
19
		</dependency>
20
		<dependency>
21
			<groupId>junit</groupId>
22
			<artifactId>junit</artifactId>
23
			<version>4.8.2</version>
24
			<scope>test</scope>
25
		</dependency>
26
		<dependency>
27
			<groupId>spring</groupId>
28
			<artifactId>spring-webmvc</artifactId>
29
			<version>${spring.version}</version>
30
		</dependency>
31
		<dependency>
32
			<groupId>eu.dnetlib</groupId>
33
			<artifactId>icm-functionality-api</artifactId>
34
			<version>[0.0.0,1.0.0-SNAPSHOT)</version>
35
		</dependency>
36
		<dependency>
37
			<groupId>eu.dnetlib</groupId>
38
			<artifactId>cnr-inspector</artifactId>
39
			<version>[0.0.0,1.0.0-SNAPSHOT)</version>
40
		</dependency>
41
		<dependency>
42
			<groupId>eu.dnetlib</groupId>
43
			<artifactId>cnr-service-common</artifactId>
44
			<version>[0.0.0,1.0.0-SNAPSHOT)</version>
45
		</dependency>
46
		<dependency>
47
			<groupId>eu.dnetlib</groupId>
48
			<artifactId>cnr-rmi-api</artifactId>
49
			<version>[0.0.0,2.0.0-SNAPSHOT)</version>
50
		</dependency>
51
	</dependencies>
52
</project>

Also available in: Unified diff