Revision 62653
Added by Alessia Bardi over 1 year ago
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/utils/MDFormatReader.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.utils; |
|
2 |
|
|
3 |
import java.io.StringReader; |
|
4 |
import java.util.List; |
|
5 |
import java.util.Map; |
|
6 |
|
|
7 |
import org.dom4j.Document; |
|
8 |
import org.dom4j.DocumentException; |
|
9 |
import org.dom4j.io.SAXReader; |
|
10 |
import org.springframework.beans.factory.annotation.Autowired; |
|
11 |
import org.xml.sax.InputSource; |
|
12 |
|
|
13 |
import com.google.common.collect.HashBasedTable; |
|
14 |
import com.google.common.collect.Table; |
|
15 |
import com.mycila.xmltool.CallBack; |
|
16 |
import com.mycila.xmltool.XMLDoc; |
|
17 |
import com.mycila.xmltool.XMLTag; |
|
18 |
|
|
19 |
import eu.dnetlib.data.provision.index.rmi.IndexServiceException; |
|
20 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
21 |
|
|
22 |
public class MDFormatReader { |
|
23 |
|
|
24 |
static class XmlUtils { |
|
25 |
|
|
26 |
/** |
|
27 |
* helper method, parses a list of fields. |
|
28 |
* |
|
29 |
* @param fields |
|
30 |
* the given fields |
|
31 |
* @return the parsed fields |
|
32 |
* @throws IndexServiceException |
|
33 |
* if cannot parse the fields |
|
34 |
*/ |
|
35 |
public static Document parse(final String xml) { |
|
36 |
try { |
|
37 |
return new SAXReader().read(new StringReader(xml)); |
|
38 |
} catch (DocumentException e) { |
|
39 |
throw new IllegalArgumentException("cannot parse: " + xml); |
|
40 |
} |
|
41 |
} |
|
42 |
|
|
43 |
public static InputSource asInputSource(final String input) throws DocumentException { |
|
44 |
return new InputSource(new StringReader(parse(input).asXML())); |
|
45 |
} |
|
46 |
} |
|
47 |
|
|
48 |
@Autowired |
|
49 |
private ServiceTools serviceTools; |
|
50 |
|
|
51 |
@Autowired |
|
52 |
private MetadataReferenceFactory mdFactory; |
|
53 |
|
|
54 |
public List<MetadataReference> listMDRefs() throws IndexClientException { |
|
55 |
return serviceTools.listMDRefs(); |
|
56 |
} |
|
57 |
|
|
58 |
public Document getFields(final MetadataReference mdRef) { |
|
59 |
String fields = serviceTools.getIndexFields(mdRef); |
|
60 |
return (fields != null) && !fields.isEmpty() ? XmlUtils.parse(fields) : null; |
|
61 |
} |
|
62 |
|
|
63 |
public Map<String, String> getAttributeMap(final MetadataReference mdRef, final String attribute) throws IndexClientException { |
|
64 |
return getAttributeTable(mdRef, attribute).column(attribute); |
|
65 |
} |
|
66 |
|
|
67 |
public Table<String, String, String> getAttributeTable(final MetadataReference mdRef, final String... attributeList) throws IndexClientException { |
|
68 |
|
|
69 |
final String fields = serviceTools.getIndexFields(mdRef); |
|
70 |
if (fields.isEmpty()) throw new IndexClientException("No result getting index layout informations"); |
|
71 |
final Table<String, String, String> t = HashBasedTable.create(); |
|
72 |
XMLDoc.from(serviceTools.getIndexFields(mdRef), false).forEach("//FIELD", new CallBack() { |
|
73 |
|
|
74 |
@Override |
|
75 |
public void execute(final XMLTag field) { |
|
76 |
|
|
77 |
for (String attribute : attributeList) { |
|
78 |
String value = null; |
|
79 |
|
|
80 |
if ("xpath".equals(attribute)) { |
|
81 |
if (!(field.hasAttribute("xpath") || field.hasAttribute("value"))) return; |
|
82 |
|
|
83 |
value = field.hasAttribute("xpath") ? field.getAttribute("xpath") : field.getAttribute("value"); |
|
84 |
} |
|
85 |
|
|
86 |
if ("weight".equals(attribute)) { |
|
87 |
if (!(field.hasAttribute(attribute))) return; |
|
88 |
|
|
89 |
value = field.hasAttribute(attribute) ? field.getAttribute(attribute) : ""; |
|
90 |
} |
|
91 |
|
|
92 |
if (value == null) { |
|
93 |
value = field.getAttribute(attribute); |
|
94 |
} |
|
95 |
|
|
96 |
t.put(field.getAttribute("name").toLowerCase(), attribute, value); |
|
97 |
} |
|
98 |
} |
|
99 |
}); |
|
100 |
return t; |
|
101 |
} |
|
102 |
|
|
103 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/model/InvalidValueTypeException.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.model; |
|
2 |
|
|
3 |
/** |
|
4 |
* A runtime exception that will be thrown if the value types of the Any objects do not match the expected types. |
|
5 |
* |
|
6 |
*/ |
|
7 |
public class InvalidValueTypeException extends RuntimeException { |
|
8 |
|
|
9 |
/** exceptions can be serialized. */ |
|
10 |
private static final long serialVersionUID = 1L; |
|
11 |
|
|
12 |
/** unsupported value type that caused this exception. */ |
|
13 |
private final Class<?> _unsupportedType; |
|
14 |
|
|
15 |
/** |
|
16 |
* Creates an InvalidValueTypeException with the given message. |
|
17 |
* |
|
18 |
* @param message |
|
19 |
* The message for the user. |
|
20 |
*/ |
|
21 |
public InvalidValueTypeException(final String message) { |
|
22 |
this(message, (Class<?>) null); |
|
23 |
} |
|
24 |
|
|
25 |
/** |
|
26 |
* Instantiates a new invalid value type exception. |
|
27 |
* |
|
28 |
* @param message |
|
29 |
* the message |
|
30 |
* @param unsupportedType |
|
31 |
* the unsupported type |
|
32 |
*/ |
|
33 |
public InvalidValueTypeException(final String message, final Class<?> unsupportedType) { |
|
34 |
super(message); |
|
35 |
_unsupportedType = unsupportedType; |
|
36 |
} |
|
37 |
|
|
38 |
/** |
|
39 |
* Instantiates a new invalid value type exception. |
|
40 |
* |
|
41 |
* @param unsupportedType |
|
42 |
* the unsupported type |
|
43 |
*/ |
|
44 |
public InvalidValueTypeException(final Class<?> unsupportedType) { |
|
45 |
this("type not supported: " + unsupportedType, unsupportedType); |
|
46 |
} |
|
47 |
|
|
48 |
/** |
|
49 |
* @param format |
|
50 |
* @param e |
|
51 |
*/ |
|
52 |
public InvalidValueTypeException(final String message, final Exception e) { |
|
53 |
super(message, e); |
|
54 |
_unsupportedType = null; |
|
55 |
} |
|
56 |
|
|
57 |
/** |
|
58 |
* Gets the unsupported type. might be null. |
|
59 |
* |
|
60 |
* @return the unsupported type |
|
61 |
*/ |
|
62 |
public Class<?> getUnsupportedType() { |
|
63 |
return _unsupportedType; |
|
64 |
} |
|
65 |
|
|
66 |
} |
|
0 | 67 |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/IndexQueryFactory.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
import java.util.List; |
|
4 |
import java.util.Map; |
|
5 |
|
|
6 |
import com.google.common.collect.BiMap; |
|
7 |
import com.google.common.collect.Lists; |
|
8 |
import com.google.common.collect.Maps; |
|
9 |
import eu.dnetlib.data.provision.index.rmi.IndexServiceException; |
|
10 |
import eu.dnetlib.functionality.cql.CqlTranslator; |
|
11 |
import eu.dnetlib.functionality.cql.lucene.TranslatedQuery; |
|
12 |
import eu.dnetlib.functionality.index.client.IndexClient; |
|
13 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
14 |
import eu.dnetlib.functionality.index.query.Pruner.Result; |
|
15 |
import eu.dnetlib.functionality.index.utils.MetadataReference; |
|
16 |
import org.springframework.beans.factory.annotation.Autowired; |
|
17 |
|
|
18 |
/** |
|
19 |
* A factory for creating IndexQuery objects. |
|
20 |
*/ |
|
21 |
public abstract class IndexQueryFactory { |
|
22 |
|
|
23 |
/** |
|
24 |
* Query tree pruner. |
|
25 |
*/ |
|
26 |
private Pruner pruner; |
|
27 |
|
|
28 |
/** |
|
29 |
* Query tree pruner. Collects parameters which affect the semantic of the cql parser. |
|
30 |
*/ |
|
31 |
private Pruner cqlPruner; |
|
32 |
|
|
33 |
/** The default query params. */ |
|
34 |
private Map<String, List<String>> defaultQueryParams; |
|
35 |
|
|
36 |
/** CqlTranslator. */ |
|
37 |
@Autowired |
|
38 |
private CqlTranslator translator; |
|
39 |
|
|
40 |
/** The browse aliases. */ |
|
41 |
@Autowired |
|
42 |
private BrowseAliases browseAliases; |
|
43 |
|
|
44 |
/** The weights. */ |
|
45 |
@Autowired |
|
46 |
private Weights weights; |
|
47 |
|
|
48 |
/** |
|
49 |
* New instance. |
|
50 |
* |
|
51 |
* @param cql |
|
52 |
* the cql |
|
53 |
* @param res |
|
54 |
* the res |
|
55 |
* @param queryLanguage |
|
56 |
* the query language |
|
57 |
* @return the index query |
|
58 |
*/ |
|
59 |
protected abstract IndexQuery newInstance(final TranslatedQuery cql, final Result res, final QueryLanguage queryLanguage); |
|
60 |
|
|
61 |
/** |
|
62 |
* Sets the query options. |
|
63 |
* |
|
64 |
* @param indexQuery |
|
65 |
* the index query |
|
66 |
* @return the index query |
|
67 |
*/ |
|
68 |
protected abstract IndexQuery setQueryOptions(final IndexQuery indexQuery, final IndexClient client); |
|
69 |
|
|
70 |
/** |
|
71 |
* Gets the index query. |
|
72 |
* |
|
73 |
* @param lang |
|
74 |
* the lang |
|
75 |
* @param query |
|
76 |
* the query |
|
77 |
* @param mdRef |
|
78 |
* the md ref |
|
79 |
* @return the index query |
|
80 |
* @throws IndexServiceException |
|
81 |
* the index service exception |
|
82 |
*/ |
|
83 |
public IndexQuery getIndexQuery(final QueryLanguage lang, final String query, final IndexClient client, final MetadataReference mdRef) |
|
84 |
throws IndexClientException { |
|
85 |
|
|
86 |
String myquery = query; |
|
87 |
|
|
88 |
if ((myquery == null) || myquery.isEmpty()) throw new IndexClientException("query cannot be empty or null"); |
|
89 |
|
|
90 |
try { |
|
91 |
final Result cqlRes = getCqlPruner().prune(getCqlPruner().parse(myquery)); |
|
92 |
final Result res = getPruner().prune(cqlRes.getNode()); |
|
93 |
|
|
94 |
final TranslatedQuery tQuery = translator.getTranslatedQuery(res.getNode(), client.getCqlValueTransformerMap(mdRef), |
|
95 |
overrideCqlParams(cqlRes.getOptionMap()), browseAliases.get(mdRef), weights.get(mdRef)); |
|
96 |
|
|
97 |
return setQueryOptions(newInstance(tQuery, res, lang), client); |
|
98 |
} catch (Exception e) { |
|
99 |
throw new IndexClientException(e); |
|
100 |
} |
|
101 |
} |
|
102 |
|
|
103 |
/** |
|
104 |
* Method overrides the default values in the defaultQueryParams with the given override map. |
|
105 |
* |
|
106 |
* @param override |
|
107 |
* the map containing the override values. |
|
108 |
* @return the overridden parameter map |
|
109 |
* |
|
110 |
*/ |
|
111 |
private Map<String, List<String>> overrideCqlParams(final Map<String, List<String>> override) { |
|
112 |
Map<String, List<String>> cqlParams = Maps.newHashMap(); |
|
113 |
cqlParams.putAll(getDefaultQueryParams()); |
|
114 |
cqlParams.putAll(override); |
|
115 |
return cqlParams; |
|
116 |
} |
|
117 |
|
|
118 |
public List<String> getBrowsableFields(final List<String> fields, final MetadataReference mdRef) throws IndexClientException { |
|
119 |
return getBrowsableFields(fields, browseAliases.get(mdRef)); |
|
120 |
} |
|
121 |
|
|
122 |
/** |
|
123 |
* Gets the list of aliases available for browse |
|
124 |
* |
|
125 |
* @param fields |
|
126 |
* list of input fields |
|
127 |
* @param aliases |
|
128 |
* key= non-browasbale-field-name, value=browsable-field-name |
|
129 |
* @return the list of browasable field names |
|
130 |
*/ |
|
131 |
public List<String> getBrowsableFields(final List<String> fields, final BiMap<String, String> aliases) { |
|
132 |
List<String> browsables = Lists.newArrayListWithExpectedSize(fields.size()); |
|
133 |
for (String f : fields) { |
|
134 |
if (aliases.containsKey(f)) { |
|
135 |
browsables.add(aliases.get(f)); |
|
136 |
} else { |
|
137 |
browsables.add(f); |
|
138 |
} |
|
139 |
} |
|
140 |
return browsables; |
|
141 |
} |
|
142 |
|
|
143 |
/** |
|
144 |
* Gets the pruner. |
|
145 |
* |
|
146 |
* @return the pruner |
|
147 |
*/ |
|
148 |
public Pruner getPruner() { |
|
149 |
return pruner; |
|
150 |
} |
|
151 |
|
|
152 |
/** |
|
153 |
* Sets the pruner. |
|
154 |
* |
|
155 |
* @param pruner |
|
156 |
* the new pruner |
|
157 |
*/ |
|
158 |
public void setPruner(final Pruner pruner) { |
|
159 |
this.pruner = pruner; |
|
160 |
} |
|
161 |
|
|
162 |
/** |
|
163 |
* Gets the cql pruner. |
|
164 |
* |
|
165 |
* @return the cql pruner |
|
166 |
*/ |
|
167 |
public Pruner getCqlPruner() { |
|
168 |
return cqlPruner; |
|
169 |
} |
|
170 |
|
|
171 |
/** |
|
172 |
* Sets the cql pruner. |
|
173 |
* |
|
174 |
* @param cqlPruner |
|
175 |
* the new cql pruner |
|
176 |
*/ |
|
177 |
public void setCqlPruner(final Pruner cqlPruner) { |
|
178 |
this.cqlPruner = cqlPruner; |
|
179 |
} |
|
180 |
|
|
181 |
/** |
|
182 |
* Gets the default query params. |
|
183 |
* |
|
184 |
* @return the default query params |
|
185 |
*/ |
|
186 |
public Map<String, List<String>> getDefaultQueryParams() { |
|
187 |
return defaultQueryParams; |
|
188 |
} |
|
189 |
|
|
190 |
/** |
|
191 |
* Sets the default query params. |
|
192 |
* |
|
193 |
* @param defaultQueryParams |
|
194 |
* the default query params |
|
195 |
*/ |
|
196 |
public void setDefaultQueryParams(final Map<String, List<String>> defaultQueryParams) { |
|
197 |
this.defaultQueryParams = defaultQueryParams; |
|
198 |
} |
|
199 |
|
|
200 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/model/ValueFormatHelper.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.model; |
|
2 |
|
|
3 |
import java.text.DateFormat; |
|
4 |
import java.text.ParseException; |
|
5 |
import java.text.SimpleDateFormat; |
|
6 |
import java.util.Date; |
|
7 |
import java.util.TimeZone; |
|
8 |
import java.util.regex.Pattern; |
|
9 |
|
|
10 |
/** |
|
11 |
* helper class for formatting and parsing Values. all methods synchronize on the used local formatter object, so you |
|
12 |
* can use the shared instance. Using multiple instances may improve performance, though, because of less |
|
13 |
* synchronization. |
|
14 |
*/ |
|
15 |
public class ValueFormatHelper { |
|
16 |
/** shared global helper instance. */ |
|
17 |
public static final ValueFormatHelper INSTANCE = new ValueFormatHelper(); |
|
18 |
|
|
19 |
/** The max. length of strings to be parsed as date. */ |
|
20 |
private static final int DATE_LENGTH = 10; |
|
21 |
|
|
22 |
/** The length of strings to be parsed as date time for (default) pattern 1. */ |
|
23 |
private static final int DATE_TIME_LENGTH_PATTERN_DEFAULT = 28; |
|
24 |
|
|
25 |
/** The length of strings to be parsed as date time for pattern 2 and 3. */ |
|
26 |
private static final int DATE_TIME_LENGTH_PATTERN_2_AND_3 = 24; |
|
27 |
|
|
28 |
/** The length of strings to be parsed as date time for pattern 4. */ |
|
29 |
private static final int DATE_TIME_LENGTH_PATTERN_4 = 20; |
|
30 |
|
|
31 |
/** formatter to create and parse standard string representations of Date values: "yyyy-MM-dd". */ |
|
32 |
private final DateFormat _formatDate = new SimpleDateFormat("yyyy-MM-dd"); |
|
33 |
|
|
34 |
/** valid Datetime value pattern with milliseconds and time zone (default for printing). */ |
|
35 |
private final DateFormat _formatDateTimePatternDefault = getDefaultDateTimeFormat(); |
|
36 |
|
|
37 |
/** valid Datetime value pattern with time zone. */ |
|
38 |
private final DateFormat _formatDateTimePattern2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); |
|
39 |
|
|
40 |
/** valid Datetime value pattern with milliseconds and time zone 'Z' (UTC). */ |
|
41 |
private final DateFormat _formatDateTimePattern3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); |
|
42 |
|
|
43 |
/** valid Datetime value pattern without milliseconds and time zone 'Z' (UTC). */ |
|
44 |
private final DateFormat _formatDateTimePattern4 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); |
|
45 |
|
|
46 |
/** pattern for checking if the string might be a date. */ |
|
47 |
private final Pattern _formatPatternDateDefault = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); |
|
48 |
|
|
49 |
/** pattern for checking if the string might be a date time for default pattern. */ |
|
50 |
private final Pattern _formatPatternTimeDefault = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}[+-]{1}\\d{4}"); |
|
51 |
|
|
52 |
/** pattern for checking if the string might be a date time for pattern 2. */ |
|
53 |
private final Pattern _formatPatternTime2 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[+-]{1}\\d{4}"); |
|
54 |
|
|
55 |
/** pattern for checking if the string might be a date time for pattern 3. */ |
|
56 |
private final Pattern _formatPatternTime3 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z"); |
|
57 |
|
|
58 |
/** pattern for checking if the string might be a date time for pattern 4. */ |
|
59 |
private final Pattern _formatPatternTime4 = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"); |
|
60 |
|
|
61 |
/** |
|
62 |
* create local instance. |
|
63 |
*/ |
|
64 |
public ValueFormatHelper() { |
|
65 |
_formatDate.setLenient(false); |
|
66 |
_formatDateTimePatternDefault.setLenient(false); |
|
67 |
_formatDateTimePattern2.setLenient(false); |
|
68 |
_formatDateTimePattern3.setLenient(false); |
|
69 |
_formatDateTimePattern3.setTimeZone(TimeZone.getTimeZone("UTC")); |
|
70 |
_formatDateTimePattern4.setLenient(false); |
|
71 |
_formatDateTimePattern4.setTimeZone(TimeZone.getTimeZone("UTC")); |
|
72 |
} |
|
73 |
|
|
74 |
/** |
|
75 |
* @return the default format for datetime values. |
|
76 |
*/ |
|
77 |
public static SimpleDateFormat getDefaultDateTimeFormat() { |
|
78 |
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); |
|
79 |
sdf.setLenient(false); |
|
80 |
return sdf; |
|
81 |
} |
|
82 |
|
|
83 |
/** |
|
84 |
* format value as Date string. |
|
85 |
* |
|
86 |
* @param value |
|
87 |
* a date value |
|
88 |
* @return formatted date. |
|
89 |
*/ |
|
90 |
public String formatDate(final Date value) { |
|
91 |
synchronized (_formatDate) { |
|
92 |
return _formatDate.format(value); |
|
93 |
} |
|
94 |
} |
|
95 |
|
|
96 |
/** |
|
97 |
* format value as DateTime string. |
|
98 |
* |
|
99 |
* @param value |
|
100 |
* a datetime value |
|
101 |
* @return formatted datetime string |
|
102 |
*/ |
|
103 |
public String formatDateTime(final Date value) { |
|
104 |
synchronized (_formatDateTimePatternDefault) { |
|
105 |
return _formatDateTimePatternDefault.format(value); |
|
106 |
} |
|
107 |
} |
|
108 |
|
|
109 |
/** |
|
110 |
* parse a date string. |
|
111 |
* |
|
112 |
* @param dateString |
|
113 |
* a date string |
|
114 |
* @return parsed Date |
|
115 |
* @throws ParseException |
|
116 |
* string has wrong format |
|
117 |
*/ |
|
118 |
public Date parseDate(final String dateString) throws ParseException { |
|
119 |
if (dateString.length() == DATE_LENGTH && _formatPatternDateDefault.matcher(dateString).matches()) { |
|
120 |
synchronized (_formatDate) { |
|
121 |
return _formatDate.parse(dateString); |
|
122 |
} |
|
123 |
} else { |
|
124 |
throw new ParseException("Length of date string '" + dateString + "' exceeds maximum date length of " + DATE_LENGTH, DATE_LENGTH); |
|
125 |
} |
|
126 |
} |
|
127 |
|
|
128 |
/** |
|
129 |
* parse a date string. |
|
130 |
* |
|
131 |
* @param dateString |
|
132 |
* a date string |
|
133 |
* @return parsed Date if correct format, else null. |
|
134 |
*/ |
|
135 |
public Date tryParseDate(final String dateString) { |
|
136 |
if (dateString.length() == DATE_LENGTH && _formatPatternDateDefault.matcher(dateString).matches()) { |
|
137 |
synchronized (_formatDate) { |
|
138 |
try { |
|
139 |
return _formatDate.parse(dateString); |
|
140 |
} catch (final ParseException ex) { |
|
141 |
; // not a date ... fine. |
|
142 |
} |
|
143 |
} |
|
144 |
} |
|
145 |
return null; |
|
146 |
} |
|
147 |
|
|
148 |
/** |
|
149 |
* parse datetime string. |
|
150 |
* |
|
151 |
* @param dateTimeString |
|
152 |
* a datetime string |
|
153 |
* @return parsed Date |
|
154 |
* @throws ParseException |
|
155 |
* string has wrong format |
|
156 |
*/ |
|
157 |
public Date parseDateTime(final String dateTimeString) throws ParseException { |
|
158 |
final Date result; |
|
159 |
final int dateLen = dateTimeString.length(); |
|
160 |
if (dateLen == DATE_TIME_LENGTH_PATTERN_DEFAULT && _formatPatternTimeDefault.matcher(dateTimeString).matches()) { |
|
161 |
synchronized (_formatDateTimePatternDefault) { |
|
162 |
result = _formatDateTimePatternDefault.parse(dateTimeString); |
|
163 |
} |
|
164 |
} else if (dateLen == DATE_TIME_LENGTH_PATTERN_2_AND_3 && _formatPatternTime2.matcher(dateTimeString).matches()) { |
|
165 |
synchronized (_formatDateTimePattern2) { |
|
166 |
result = _formatDateTimePattern2.parse(dateTimeString); |
|
167 |
} |
|
168 |
} else if (dateLen == DATE_TIME_LENGTH_PATTERN_2_AND_3 && _formatPatternTime3.matcher(dateTimeString).matches()) { |
|
169 |
synchronized (_formatDateTimePattern3) { |
|
170 |
result = _formatDateTimePattern3.parse(dateTimeString); |
|
171 |
} |
|
172 |
} else if (dateLen == DATE_TIME_LENGTH_PATTERN_4 && _formatPatternTime4.matcher(dateTimeString).matches()) { |
|
173 |
synchronized (_formatDateTimePattern4) { |
|
174 |
result = _formatDateTimePattern4.parse(dateTimeString); |
|
175 |
} |
|
176 |
} else { |
|
177 |
throw new ParseException("Length '" + dateTimeString.length() + "' of datetime string '" + dateTimeString |
|
178 |
+ "' doesn't match expected pattern length", dateTimeString.length()); |
|
179 |
} |
|
180 |
return result; |
|
181 |
} |
|
182 |
|
|
183 |
/** |
|
184 |
* parse datetime string. |
|
185 |
* |
|
186 |
* @param dateTimeString |
|
187 |
* a datetime string |
|
188 |
* @return parsed Date if correct format, else null; |
|
189 |
*/ |
|
190 |
public Date tryParseDateTime(final String dateTimeString) { |
|
191 |
Date result = null; |
|
192 |
try { |
|
193 |
switch (dateTimeString.length()) { |
|
194 |
case DATE_TIME_LENGTH_PATTERN_DEFAULT: |
|
195 |
if (_formatPatternTimeDefault.matcher(dateTimeString).matches()) { |
|
196 |
synchronized (_formatDateTimePatternDefault) { |
|
197 |
result = _formatDateTimePatternDefault.parse(dateTimeString); |
|
198 |
} |
|
199 |
} |
|
200 |
break; |
|
201 |
case DATE_TIME_LENGTH_PATTERN_2_AND_3: |
|
202 |
if (_formatPatternTime2.matcher(dateTimeString).matches()) { |
|
203 |
synchronized (_formatDateTimePattern2) { |
|
204 |
result = _formatDateTimePattern2.parse(dateTimeString); |
|
205 |
} |
|
206 |
} else if (_formatPatternTime3.matcher(dateTimeString).matches()) { |
|
207 |
synchronized (_formatDateTimePattern3) { |
|
208 |
result = _formatDateTimePattern3.parse(dateTimeString); |
|
209 |
} |
|
210 |
} |
|
211 |
break; |
|
212 |
case DATE_TIME_LENGTH_PATTERN_4: |
|
213 |
if (_formatPatternTime4.matcher(dateTimeString).matches()) { |
|
214 |
synchronized (_formatDateTimePattern4) { |
|
215 |
result = _formatDateTimePattern4.parse(dateTimeString); |
|
216 |
} |
|
217 |
} |
|
218 |
break; |
|
219 |
default: |
|
220 |
break; |
|
221 |
} |
|
222 |
} catch (final ParseException ex) { |
|
223 |
; // not a datetime ... fine. |
|
224 |
} |
|
225 |
return result; |
|
226 |
} |
|
227 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/Pruner.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
import java.io.IOException; |
|
4 |
import java.util.*; |
|
5 |
import java.util.stream.Collectors; |
|
6 |
import java.util.stream.Stream; |
|
7 |
|
|
8 |
import com.google.common.collect.Iterables; |
|
9 |
import com.google.common.collect.Lists; |
|
10 |
import com.google.common.collect.Maps; |
|
11 |
import org.apache.commons.logging.Log; |
|
12 |
import org.apache.commons.logging.LogFactory; |
|
13 |
import org.z3950.zing.cql.*; |
|
14 |
|
|
15 |
/** |
|
16 |
* Use this class to cleanup a CQL tree and obtain all the options |
|
17 |
* |
|
18 |
* @author marko & claudio |
|
19 |
* |
|
20 |
*/ |
|
21 |
public class Pruner { |
|
22 |
private static final Log log = LogFactory.getLog(Pruner.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
23 |
|
|
24 |
/** |
|
25 |
* All options have to be in this namespace. |
|
26 |
*/ |
|
27 |
public static final String DNET_URI = "NAMESPACE"; |
|
28 |
|
|
29 |
private String optionUri = DNET_URI; |
|
30 |
|
|
31 |
/** |
|
32 |
* Helper method, parse a given CQL string. |
|
33 |
* |
|
34 |
* @param cqlQuery |
|
35 |
* @return the parsed CQLNode |
|
36 |
* @throws CQLParseException |
|
37 |
* @throws IOException |
|
38 |
*/ |
|
39 |
CQLNode parse(final String cqlQuery) throws CQLParseException, IOException { |
|
40 |
return new CQLParser().parse(cqlQuery); |
|
41 |
} |
|
42 |
|
|
43 |
class Result { |
|
44 |
private CQLNode node; |
|
45 |
private List<String> options; |
|
46 |
|
|
47 |
public Result(final CQLNode node, final List<String> options) { |
|
48 |
super(); |
|
49 |
this.node = node; |
|
50 |
this.options = options; |
|
51 |
} |
|
52 |
|
|
53 |
public Result(final CQLNode node, final Iterable<String> concat) { |
|
54 |
this.node = node; |
|
55 |
this.options = Lists.newArrayList(concat); |
|
56 |
} |
|
57 |
|
|
58 |
public CQLNode getNode() { |
|
59 |
return node; |
|
60 |
} |
|
61 |
|
|
62 |
public void setNode(final CQLNode node) { |
|
63 |
this.node = node; |
|
64 |
} |
|
65 |
|
|
66 |
public List<String> getOptions() { |
|
67 |
return options; |
|
68 |
} |
|
69 |
|
|
70 |
public void setOptions(final List<String> options) { |
|
71 |
this.options = options; |
|
72 |
} |
|
73 |
|
|
74 |
public Map<String, List<String>> getOptionMap() { |
|
75 |
Map<String, List<String>> res = new HashMap<String, List<String>>(); |
|
76 |
for (String opt : options) { |
|
77 |
String[] k = opt.split("="); |
|
78 |
List<String> l = res.get(k[0]); |
|
79 |
if(l == null) |
|
80 |
l = new ArrayList<String>(); |
|
81 |
l.add(k[1]); |
|
82 |
res.put(k[0], l); |
|
83 |
} |
|
84 |
return res; |
|
85 |
} |
|
86 |
} |
|
87 |
|
|
88 |
/** |
|
89 |
* Remove all options from a given CQL AST and return all the options. |
|
90 |
* |
|
91 |
* The CQL tree is modified. |
|
92 |
* |
|
93 |
* @param root |
|
94 |
* cql tree |
|
95 |
* @return pair containing a new root node and a list of options |
|
96 |
*/ |
|
97 |
public Result prune(final CQLNode root) { |
|
98 |
return prune(new HashMap<String, String>(), root); |
|
99 |
} |
|
100 |
|
|
101 |
/** |
|
102 |
* Actual recursive implementation, dispatches the implementation to the appropriate overloaded method. |
|
103 |
* |
|
104 |
* @param prefixes |
|
105 |
* @param root |
|
106 |
* @return the pruned result |
|
107 |
*/ |
|
108 |
public Result prune(final Map<String, String> prefixes, final CQLNode root) { |
|
109 |
|
|
110 |
if (root instanceof CQLBooleanNode) |
|
111 |
return prune(prefixes, (CQLBooleanNode) root); |
|
112 |
|
|
113 |
if (root instanceof CQLPrefixNode) |
|
114 |
return prune(prefixes, (CQLPrefixNode) root); |
|
115 |
|
|
116 |
if (root instanceof CQLSortNode) |
|
117 |
return prune(prefixes, (CQLSortNode) root); |
|
118 |
|
|
119 |
return new Result(root, new ArrayList<String>()); |
|
120 |
} |
|
121 |
|
|
122 |
/** |
|
123 |
* If the current node is a cql "sort" node, just return the inner subtree. |
|
124 |
* |
|
125 |
* @param prefixes |
|
126 |
* @param node |
|
127 |
* @return the pruned result |
|
128 |
*/ |
|
129 |
public Result prune(final Map<String, String> prefixes, final CQLSortNode node) { |
|
130 |
Result res = prune(prefixes, node.subtree); |
|
131 |
node.subtree = res.getNode(); |
|
132 |
res.setNode(node); |
|
133 |
return res; |
|
134 |
} |
|
135 |
|
|
136 |
/** |
|
137 |
* If the current node is a cql "prefix" node, add his namespace declaration to the current list of namespaces and |
|
138 |
* return the pruned inner subtree. |
|
139 |
* |
|
140 |
* If the prefix node contains only one single option element, we have to return null. (TODO: perhaps there is a |
|
141 |
* better solution). |
|
142 |
* |
|
143 |
* @param prefixes |
|
144 |
* @param node |
|
145 |
* @return the pruned result |
|
146 |
*/ |
|
147 |
public Result prune(final Map<String, String> prefixes, final CQLPrefixNode node) { |
|
148 |
final HashMap<String, String> subPrefixes = Maps.newHashMap(prefixes); |
|
149 |
subPrefixes.put(node.prefix.name, node.prefix.identifier); |
|
150 |
|
|
151 |
if (isOption(subPrefixes, node.subtree)) |
|
152 |
return new Result(null, Lists.newArrayList(getOption(node.subtree))); |
|
153 |
|
|
154 |
boolean pruneThisPrefix = node.prefix.identifier.equals(optionUri); |
|
155 |
if(pruneThisPrefix) |
|
156 |
return prune(subPrefixes, node.subtree); |
|
157 |
|
|
158 |
Result res = prune(subPrefixes, node.subtree); |
|
159 |
node.subtree = res.getNode(); |
|
160 |
res.setNode(node); |
|
161 |
return res; |
|
162 |
|
|
163 |
} |
|
164 |
|
|
165 |
/** |
|
166 |
* boolean prunes are handled in the prune(prefix, node, left, right). |
|
167 |
* |
|
168 |
* @param prefixes |
|
169 |
* @param node |
|
170 |
* @return the pruned result |
|
171 |
*/ |
|
172 |
public Result prune(final Map<String, String> prefixes, final CQLBooleanNode node) { |
|
173 |
return prune(prefixes, node, node.left, node.right); |
|
174 |
} |
|
175 |
|
|
176 |
/** |
|
177 |
* Detects if a left or right side of a boolean node is a option term, and returns the other side (recursively |
|
178 |
* pruned). It also returns the accumulated options along the way. |
|
179 |
* |
|
180 |
* @param prefixes |
|
181 |
* @param bool |
|
182 |
* @param left |
|
183 |
* @param right |
|
184 |
* @return the pruned result |
|
185 |
*/ |
|
186 |
public Result prune(final Map<String, String> prefixes, final CQLBooleanNode bool, final CQLNode left, final CQLNode right) { |
|
187 |
|
|
188 |
if (isOption(prefixes, left) && isOption(prefixes, right)) { |
|
189 |
return new Result(null, Stream.of(trimOption(prefixes, left, right), trimOption(prefixes, right, left)) |
|
190 |
.filter(Objects::nonNull) |
|
191 |
.map(i -> i.getOptions()) |
|
192 |
.map(i -> i.stream()) |
|
193 |
.flatMap(i -> i) |
|
194 |
.collect(Collectors.toList())); |
|
195 |
} |
|
196 |
|
|
197 |
Result res = anyNotNull(trimOption(prefixes, left, right), trimOption(prefixes, right, left)); |
|
198 |
|
|
199 |
if (res != null) |
|
200 |
return res; |
|
201 |
|
|
202 |
final Result leftResult = prune(prefixes, left); |
|
203 |
final Result rightResult = prune(prefixes, right); |
|
204 |
|
|
205 |
bool.left = leftResult.getNode(); |
|
206 |
bool.right = rightResult.getNode(); |
|
207 |
return new Result(clean(bool), Iterables.concat(leftResult.getOptions(), rightResult.getOptions())); |
|
208 |
} |
|
209 |
|
|
210 |
public <T> T anyNotNull(T a, T b) { |
|
211 |
if (a != null) |
|
212 |
return a; |
|
213 |
return b; |
|
214 |
} |
|
215 |
|
|
216 |
/** |
|
217 |
* Trims an option from a boolean node if one if it's sides is an option term. |
|
218 |
* |
|
219 |
* Intended to be used once for each sides and then swap. |
|
220 |
* |
|
221 |
* @param prefixes |
|
222 |
* @param a |
|
223 |
* @param b |
|
224 |
* @return the pruned result |
|
225 |
*/ |
|
226 |
public Result trimOption(final Map<String, String> prefixes, final CQLNode a, final CQLNode b) { |
|
227 |
log.debug("trim option?" + prefixes + " a " + a.toCQL()); |
|
228 |
if (isOption(prefixes, a)) { |
|
229 |
log.debug("IS OPTION..."); |
|
230 |
return trimOption(prefixes, prefixFromOption(a), getOption(a), b); |
|
231 |
} |
|
232 |
log.debug("IS NOT OPTION"); |
|
233 |
return null; |
|
234 |
} |
|
235 |
|
|
236 |
/** |
|
237 |
* prune(prefixes, bool, left, right) uses this helper method to do the dirty job: |
|
238 |
* |
|
239 |
* we have to detect if a term node is a term option node. by checking the namespace uri associated with the term |
|
240 |
* prefix according the the current namespace prefix scope (held in prefixes, which is passed down recursively by |
|
241 |
* copy). |
|
242 |
* |
|
243 |
* @param prefixes |
|
244 |
* @param ns |
|
245 |
* @param o |
|
246 |
* @param subtree |
|
247 |
* @return the pruned result |
|
248 |
*/ |
|
249 |
public Result trimOption(final Map<String, String> prefixes, final String ns, final String o, final CQLNode subtree) { |
|
250 |
log.debug("trimming " + prefixes + " ns " + ns + " o " + o); |
|
251 |
|
|
252 |
final String namespaceUri = prefixes.get(ns); |
|
253 |
|
|
254 |
if (!optionUri.equals(namespaceUri)) { |
|
255 |
return null; |
|
256 |
} |
|
257 |
|
|
258 |
final Result res = prune(prefixes, subtree); |
|
259 |
return new Result(res.getNode(), Iterables.concat(Lists.newArrayList(o), res.getOptions())); |
|
260 |
} |
|
261 |
|
|
262 |
/** |
|
263 |
* Drop a boolean node (and, or etc) if one of the sides has been dropped. |
|
264 |
* |
|
265 |
* @param bool |
|
266 |
* @return the pruned result |
|
267 |
*/ |
|
268 |
private CQLNode clean(final CQLBooleanNode bool) { |
|
269 |
if (bool.left == null) |
|
270 |
return bool.right; |
|
271 |
if (bool.right == null) |
|
272 |
return bool.left; |
|
273 |
return bool; |
|
274 |
} |
|
275 |
|
|
276 |
////////////////// helpers |
|
277 |
|
|
278 |
public String getOption(final CQLNode node) { |
|
279 |
return indexFromOption(node) + "=" + termFromOption(node); |
|
280 |
} |
|
281 |
|
|
282 |
private String indexFromOption(final CQLNode node) { |
|
283 |
return ((CQLTermNode) node).getIndex().replaceAll("[a-z]*\\.(.+)", "$1"); |
|
284 |
} |
|
285 |
|
|
286 |
private String termFromOption(final CQLNode node) { |
|
287 |
return ((CQLTermNode) node).getTerm(); |
|
288 |
} |
|
289 |
|
|
290 |
public String prefixFromOption(final String option) { |
|
291 |
return option.replaceAll("([a-z]*)\\..+", "$1"); |
|
292 |
} |
|
293 |
|
|
294 |
public String prefixFromOption(final CQLNode node) { |
|
295 |
if (node instanceof CQLTermNode) |
|
296 |
return prefixFromOption(((CQLTermNode) node).getIndex()); |
|
297 |
|
|
298 |
return null; |
|
299 |
} |
|
300 |
|
|
301 |
public boolean isOption(final Map<String, String> prefixes, final String option) { |
|
302 |
return prefixes.containsKey(prefixFromOption(option)) && prefixes.get(prefixFromOption(option)).equals(getOptionUri()); |
|
303 |
} |
|
304 |
|
|
305 |
public boolean isOption(final Map<String, String> prefixes, final CQLNode node) { |
|
306 |
if (node instanceof CQLTermNode) |
|
307 |
return isOption(prefixes, ((CQLTermNode) node).getIndex()); |
|
308 |
|
|
309 |
return false; |
|
310 |
} |
|
311 |
|
|
312 |
public String getOptionUri() { |
|
313 |
return optionUri; |
|
314 |
} |
|
315 |
|
|
316 |
public void setOptionUri(String optionUri) { |
|
317 |
this.optionUri = optionUri; |
|
318 |
} |
|
319 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/model/Value.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.model; |
|
2 |
|
|
3 |
import java.util.Date; |
|
4 |
|
|
5 |
/** |
|
6 |
* Interface for a value object, used if the any object is of type string, double, boolean, long, date or date time. |
|
7 |
*/ |
|
8 |
public interface Value extends Any { |
|
9 |
|
|
10 |
/** |
|
11 |
* @return The string representation |
|
12 |
*/ |
|
13 |
String asString(); |
|
14 |
|
|
15 |
/** |
|
16 |
* @return The double representation, an InvalidValueTypeException is thrown if the value is not a number. If value |
|
17 |
* is a string then this is tried to be converted to a Double. |
|
18 |
*/ |
|
19 |
Double asDouble(); |
|
20 |
|
|
21 |
/** |
|
22 |
* @return The long representation, an InvalidValueTypeException is thrown if the value is not a number. If value is |
|
23 |
* a string then this is tried to be converted to a Long. |
|
24 |
*/ |
|
25 |
Long asLong(); |
|
26 |
|
|
27 |
/** |
|
28 |
* @return The boolean representation, an InvalidValueTypeException is thrown if the value is not of type boolean. |
|
29 |
* If value is a string then this is tried to be converted to a boolean. |
|
30 |
*/ |
|
31 |
Boolean asBoolean(); |
|
32 |
|
|
33 |
/** |
|
34 |
* @return The date representation, an InvalidValueTypeException is thrown if the value is not of type date or |
|
35 |
* datetime. If value is a string then this is tried to be converted to a date. |
|
36 |
*/ |
|
37 |
Date asDate(); |
|
38 |
|
|
39 |
/** |
|
40 |
* @return The date time representation, an InvalidValueTypeException is thrown if the value is not of type |
|
41 |
* datetime. If value is a string then this is tried to be converted to a datetime. |
|
42 |
*/ |
|
43 |
Date asDateTime(); |
|
44 |
|
|
45 |
/** |
|
46 |
* @return the value object |
|
47 |
*/ |
|
48 |
Object getObject(); |
|
49 |
} |
|
0 | 50 |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/IndexQuery.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
/** |
|
4 |
* The Class IndexQuery. |
|
5 |
*/ |
|
6 |
public interface IndexQuery { |
|
7 |
|
|
8 |
IndexQuery setQueryOffset(int offset); |
|
9 |
|
|
10 |
IndexQuery setQueryLimit(int limit); |
|
11 |
|
|
12 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/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" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
|
3 |
<parent> |
|
4 |
<groupId>eu.dnetlib</groupId> |
|
5 |
<artifactId>dnet45-parent</artifactId> |
|
6 |
<version>1.0.0</version> |
|
7 |
<relativePath /> |
|
8 |
</parent> |
|
9 |
<modelVersion>4.0.0</modelVersion> |
|
10 |
<groupId>eu.dnetlib</groupId> |
|
11 |
<artifactId>dnet-index-client</artifactId> |
|
12 |
<packaging>jar</packaging> |
|
13 |
<version>3.0.0</version> |
|
14 |
<scm> |
|
15 |
<developerConnection>scm:svn:https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-index-client/tags/dnet-index-client-3.0.0</developerConnection> |
|
16 |
</scm> |
|
17 |
<dependencies> |
|
18 |
<dependency> |
|
19 |
<groupId>org.springframework</groupId> |
|
20 |
<artifactId>spring-beans</artifactId> |
|
21 |
<version>${spring.version}</version> |
|
22 |
</dependency> |
|
23 |
<dependency> |
|
24 |
<groupId>junit</groupId> |
|
25 |
<artifactId>junit</artifactId> |
|
26 |
<version>${junit.version}</version> |
|
27 |
<scope>test</scope> |
|
28 |
</dependency> |
|
29 |
<dependency> |
|
30 |
<groupId>org.mockito</groupId> |
|
31 |
<artifactId>mockito-core</artifactId> |
|
32 |
<version>${mockito.version}</version> |
|
33 |
<scope>test</scope> |
|
34 |
</dependency> |
|
35 |
<dependency> |
|
36 |
<groupId>com.google.code.gson</groupId> |
|
37 |
<artifactId>gson</artifactId> |
|
38 |
<version>${google.gson.version}</version> |
|
39 |
</dependency> |
|
40 |
|
|
41 |
<dependency> |
|
42 |
<groupId>com.mycila</groupId> |
|
43 |
<artifactId>xmltool</artifactId> |
|
44 |
<version>3.3</version> |
|
45 |
</dependency> |
|
46 |
<dependency> |
|
47 |
<groupId>org.apache.solr</groupId> |
|
48 |
<artifactId>solr-solrj</artifactId> |
|
49 |
<version>7.5.0</version> |
|
50 |
<exclusions> |
|
51 |
<exclusion> |
|
52 |
<artifactId>wstx-asl</artifactId> |
|
53 |
<groupId>org.codehaus.woodstox</groupId> |
|
54 |
</exclusion> |
|
55 |
<exclusion> |
|
56 |
<artifactId>jcl-over-slf4j</artifactId> |
|
57 |
<groupId>org.slf4j</groupId> |
|
58 |
</exclusion> |
|
59 |
</exclusions> |
|
60 |
</dependency> |
|
61 |
<dependency> |
|
62 |
<groupId>eu.dnetlib</groupId> |
|
63 |
<artifactId>dnet-index-solr-common</artifactId> |
|
64 |
<version>[3.0.0,4.0.0)</version> |
|
65 |
</dependency> |
|
66 |
<dependency> |
|
67 |
<groupId>eu.dnetlib</groupId> |
|
68 |
<artifactId>cnr-service-common</artifactId> |
|
69 |
<version>[2.1.0,3.0.0)</version> |
|
70 |
</dependency> |
|
71 |
<dependency> |
|
72 |
<groupId>eu.dnetlib</groupId> |
|
73 |
<artifactId>cnr-cql-utils</artifactId> |
|
74 |
<version>[2.0.0,3.0.0)</version> |
|
75 |
</dependency> |
|
76 |
<dependency> |
|
77 |
<groupId>eu.dnetlib</groupId> |
|
78 |
<artifactId>dnet-data-provision-rmi</artifactId> |
|
79 |
<version>[1.0.0,2.0.0)</version> |
|
80 |
</dependency> |
|
81 |
</dependencies> |
|
82 |
</project> |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/QueryLanguage.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
public enum QueryLanguage { |
|
4 |
CQL, SOLR |
|
5 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/Weights.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
import java.util.HashMap; |
|
4 |
import java.util.Map; |
|
5 |
|
|
6 |
import org.apache.commons.logging.Log; |
|
7 |
import org.apache.commons.logging.LogFactory; |
|
8 |
import org.springframework.beans.factory.annotation.Autowired; |
|
9 |
|
|
10 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
11 |
import eu.dnetlib.functionality.index.utils.MDFormatReader; |
|
12 |
import eu.dnetlib.functionality.index.utils.MetadataReference; |
|
13 |
import eu.dnetlib.functionality.index.utils.ServiceTools; |
|
14 |
|
|
15 |
public class Weights extends HashMap<MetadataReference, Map<String, String>> { |
|
16 |
|
|
17 |
private static final long serialVersionUID = -3517914310574484765L; |
|
18 |
|
|
19 |
private static final Log log = LogFactory.getLog(Weights.class); // NOPMD by marko on 11/24/08 5:02 PM |
|
20 |
|
|
21 |
@Autowired |
|
22 |
private ServiceTools serviceTools; |
|
23 |
|
|
24 |
@Autowired |
|
25 |
private MDFormatReader mdFormatReader; |
|
26 |
|
|
27 |
public Weights() { |
|
28 |
super(); |
|
29 |
} |
|
30 |
|
|
31 |
public void initialize() throws IndexClientException { |
|
32 |
log.info("initializing weights"); |
|
33 |
|
|
34 |
for (MetadataReference mdRef : serviceTools.listMDRefs()) { |
|
35 |
put(mdRef, mdFormatReader.getAttributeMap(mdRef, "weight")); |
|
36 |
} |
|
37 |
log.info("weights initialization completed"); |
|
38 |
|
|
39 |
} |
|
40 |
|
|
41 |
@Override |
|
42 |
public Map<String, String> put(final MetadataReference mdRef, final Map<String, String> w) { |
|
43 |
log.info("[" + mdRef + "]" + " adding weights: " + w); |
|
44 |
return super.put(mdRef, w); |
|
45 |
} |
|
46 |
|
|
47 |
@Override |
|
48 |
public Map<String, String> get(final Object mdRef) { |
|
49 |
Map<String, String> map = super.get(mdRef); |
|
50 |
return map != null ? map : initAndGet(mdRef); |
|
51 |
} |
|
52 |
|
|
53 |
private Map<String, String> initAndGet(final Object mdRef) { |
|
54 |
try { |
|
55 |
initialize(); |
|
56 |
} catch (IndexClientException e) { |
|
57 |
throw new RuntimeException(e); |
|
58 |
} |
|
59 |
return super.get(mdRef); |
|
60 |
} |
|
61 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/test/java/eu/dnetlib/functionality/index/query/SolrIndexQueryFactoryTest.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
import java.util.List; |
|
4 |
|
|
5 |
import com.google.common.collect.BiMap; |
|
6 |
import com.google.common.collect.HashBiMap; |
|
7 |
import com.google.common.collect.Lists; |
|
8 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
9 |
import org.junit.Assert; |
|
10 |
import org.junit.Before; |
|
11 |
import org.junit.Test; |
|
12 |
|
|
13 |
public class SolrIndexQueryFactoryTest { |
|
14 |
|
|
15 |
IndexQueryFactory factory; |
|
16 |
BiMap<String, String> browsingAliases = HashBiMap.create(); |
|
17 |
|
|
18 |
@Before |
|
19 |
public void setUp() throws Exception { |
|
20 |
factory = new SolrIndexQueryFactory(); |
|
21 |
browsingAliases.put("field1", "field1ForBrowsing"); |
|
22 |
browsingAliases.put("field2", "field2ForBrowsing"); |
|
23 |
} |
|
24 |
|
|
25 |
@Test |
|
26 |
public void testGetBrowsableFields() throws IndexClientException { |
|
27 |
List<String> browsables = factory.getBrowsableFields(Lists.newArrayList("field1", "field3", "field2"), browsingAliases); |
|
28 |
Assert.assertEquals(Lists.newArrayList("field1ForBrowsing", "field3", "field2ForBrowsing"), browsables); |
|
29 |
} |
|
30 |
|
|
31 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/utils/MetadataReferenceFactory.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.utils; |
|
2 |
|
|
3 |
|
|
4 |
public class MetadataReferenceFactory { |
|
5 |
|
|
6 |
public static MetadataReference getMetadata(final String format, final String layout, final String interpretation) { |
|
7 |
return new MetadataReference(format, layout, interpretation); |
|
8 |
} |
|
9 |
|
|
10 |
public static MetadataReference decodeMetadata(final String encoded) { |
|
11 |
String[] split = encoded.split("-"); |
|
12 |
if (split.length == 3) return getMetadata(split[0], split[1], split[2]); |
|
13 |
|
|
14 |
throw new IllegalStateException("malformed metadata reference: " + encoded); |
|
15 |
} |
|
16 |
|
|
17 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/utils/MetadataReference.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.utils; |
|
2 |
|
|
3 |
|
|
4 |
import com.google.common.collect.ComparisonChain; |
|
5 |
|
|
6 |
/** |
|
7 |
* Container class for metadata format, layout and interpretation. |
|
8 |
* |
|
9 |
* @author claudio |
|
10 |
* |
|
11 |
*/ |
|
12 |
public class MetadataReference { |
|
13 |
|
|
14 |
/** |
|
15 |
* Metadata format. |
|
16 |
*/ |
|
17 |
private String format; |
|
18 |
|
|
19 |
/** |
|
20 |
* Metadata layout. |
|
21 |
*/ |
|
22 |
private String layout; |
|
23 |
|
|
24 |
/** |
|
25 |
* Metadata interpretation. |
|
26 |
*/ |
|
27 |
private String interpretation; |
|
28 |
|
|
29 |
/** |
|
30 |
* Constructor for MetadataReference. |
|
31 |
* |
|
32 |
* @param format |
|
33 |
* Metadata format |
|
34 |
* @param layout |
|
35 |
* Metadata layout |
|
36 |
* @param interpretation |
|
37 |
* Metadata interpretation |
|
38 |
*/ |
|
39 |
public MetadataReference(final String format, final String layout, final String interpretation) { |
|
40 |
this.format = format; |
|
41 |
this.layout = layout; |
|
42 |
this.interpretation = interpretation; |
|
43 |
} |
|
44 |
|
|
45 |
public String getFormat() { |
|
46 |
return format; |
|
47 |
} |
|
48 |
|
|
49 |
public String getLayout() { |
|
50 |
return layout; |
|
51 |
} |
|
52 |
|
|
53 |
public String getInterpretation() { |
|
54 |
return interpretation; |
|
55 |
} |
|
56 |
|
|
57 |
@Override |
|
58 |
public boolean equals(final Object that) { |
|
59 |
|
|
60 |
if (!(that instanceof MetadataReference)) |
|
61 |
return false; |
|
62 |
|
|
63 |
final MetadataReference mdRef = (MetadataReference) that; |
|
64 |
|
|
65 |
return ComparisonChain.start() |
|
66 |
.compare(this.format, mdRef.getFormat()) |
|
67 |
.compare(this.layout, mdRef.getLayout()) |
|
68 |
.compare(this.interpretation, mdRef.getInterpretation()) |
|
69 |
.result() == 0; |
|
70 |
} |
|
71 |
|
|
72 |
@Override |
|
73 |
public int hashCode() { |
|
74 |
return getFormat().hashCode() + getLayout().hashCode() + getInterpretation().hashCode(); |
|
75 |
} |
|
76 |
|
|
77 |
@Override |
|
78 |
public String toString() { |
|
79 |
return getFormat() + "-" + getLayout() + "-" + getInterpretation(); |
|
80 |
} |
|
81 |
|
|
82 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/query/SolrIndexQueryResponseFactory.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.query; |
|
2 |
|
|
3 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
4 |
import eu.dnetlib.functionality.index.utils.MetadataReference; |
|
5 |
import org.apache.solr.client.solrj.response.QueryResponse; |
|
6 |
|
|
7 |
/** |
|
8 |
* The Class SolrIndexQueryResponseFactory. |
|
9 |
*/ |
|
10 |
public class SolrIndexQueryResponseFactory extends QueryResponseFactory<QueryResponse> { |
|
11 |
|
|
12 |
/** |
|
13 |
* {@inheritDoc} |
|
14 |
* |
|
15 |
* @throws IndexClientException |
|
16 |
* |
|
17 |
* @see QueryResponseFactory#getQueryResponseParser(IndexQueryResponse, |
|
18 |
* MetadataReference) |
|
19 |
*/ |
|
20 |
@Override |
|
21 |
public QueryResponseParser getQueryResponseParser(final IndexQueryResponse<QueryResponse> queryRsp, final MetadataReference mdRef) |
|
22 |
throws IndexClientException { |
|
23 |
|
|
24 |
QueryResponse response = queryRsp.getContextualQueryResponse(); |
|
25 |
return new SolrResponseParser(highlightUtils, browseAliases.get(mdRef), returnEmptyFields, includeRanking, response); |
|
26 |
} |
|
27 |
|
|
28 |
} |
modules/dnet-index-client/tags/dnet-index-client-3.0.0/src/main/java/eu/dnetlib/functionality/index/client/solr/SolrIndexClient.java | ||
---|---|---|
1 |
package eu.dnetlib.functionality.index.client.solr; |
|
2 |
|
|
3 |
import java.io.IOException; |
|
4 |
import java.text.SimpleDateFormat; |
|
5 |
import java.util.*; |
|
6 |
|
|
7 |
import com.google.common.collect.BiMap; |
|
8 |
import com.google.common.collect.Maps; |
|
9 |
import eu.dnetlib.data.provision.index.rmi.BrowsingRow; |
|
10 |
import eu.dnetlib.data.provision.index.rmi.GroupResult; |
|
11 |
import eu.dnetlib.data.provision.index.rmi.IndexServiceException; |
|
12 |
import eu.dnetlib.functionality.cql.CqlValueTransformerMap; |
|
13 |
import eu.dnetlib.functionality.index.client.IndexClient; |
|
14 |
import eu.dnetlib.functionality.index.client.IndexClientException; |
|
15 |
import eu.dnetlib.functionality.index.client.response.BrowseEntry; |
|
16 |
import eu.dnetlib.functionality.index.client.response.BrowseValueEntry; |
|
17 |
import eu.dnetlib.functionality.index.client.response.LookupResponse; |
|
18 |
import eu.dnetlib.functionality.index.model.Any.ValueType; |
|
19 |
import eu.dnetlib.functionality.index.query.*; |
|
20 |
import eu.dnetlib.functionality.index.solr.cql.SolrTypeBasedCqlValueTransformerMapFactory; |
|
21 |
import eu.dnetlib.functionality.index.solr.feed.StreamingInputDocumentFactory; |
|
22 |
import eu.dnetlib.functionality.index.utils.MetadataReference; |
|
23 |
import eu.dnetlib.functionality.index.utils.ZkServers; |
|
24 |
import eu.dnetlib.miscutils.datetime.HumanTime; |
|
25 |
import eu.dnetlib.miscutils.functional.UnaryFunction; |
|
26 |
import org.apache.commons.lang3.StringUtils; |
|
27 |
import org.apache.commons.logging.Log; |
|
28 |
import org.apache.commons.logging.LogFactory; |
|
29 |
import org.apache.solr.client.solrj.SolrClient; |
|
30 |
import org.apache.solr.client.solrj.SolrQuery; |
|
31 |
import org.apache.solr.client.solrj.SolrServerException; |
|
32 |
import org.apache.solr.client.solrj.impl.CloudSolrClient; |
|
33 |
import org.apache.solr.client.solrj.request.LukeRequest; |
|
34 |
import org.apache.solr.client.solrj.response.LukeResponse; |
|
35 |
import org.apache.solr.client.solrj.response.LukeResponse.FieldInfo; |
|
36 |
import org.apache.solr.client.solrj.response.QueryResponse; |
|
37 |
import org.apache.solr.client.solrj.response.UpdateResponse; |
|
38 |
import org.apache.solr.common.SolrInputDocument; |
|
39 |
|
|
40 |
/** |
|
41 |
* The Class SolrIndexClient. |
|
42 |
*/ |
|
43 |
public class SolrIndexClient implements IndexClient { |
|
44 |
|
|
45 |
private static final Log log = LogFactory.getLog(SolrIndexClient.class); |
|
46 |
|
|
47 |
private static final String INDEX_RECORD_RESULT_FIELD = "dnetResult"; |
|
48 |
|
|
49 |
private static String ZK_ADDRESS = "address"; |
|
50 |
|
|
51 |
/** The format. */ |
|
52 |
private String format; |
|
53 |
|
|
54 |
/** The layout. */ |
|
55 |
private String layout; |
|
56 |
|
|
57 |
/** The interpretation. */ |
|
58 |
private String interpretation; |
|
59 |
|
|
60 |
protected Map<String, String> serviceProperties; |
|
61 |
|
|
62 |
/** The client. */ |
|
63 |
private CloudSolrClient client; |
|
64 |
|
|
65 |
private SolrIndexQueryFactory solrIndexQueryFactory; |
|
66 |
|
|
67 |
/** The query response factory. */ |
|
68 |
private QueryResponseFactory<QueryResponse> queryResponseFactory; |
|
69 |
|
|
70 |
private SolrTypeBasedCqlValueTransformerMapFactory tMapFactory; |
|
71 |
|
|
72 |
/** |
|
73 |
* The Constructor. |
|
74 |
* |
|
75 |
* @param format |
|
76 |
* the format |
|
77 |
* @param layout |
|
78 |
* the layout |
|
79 |
* @param interpretation |
|
80 |
* the interpretation |
|
81 |
* @param serviceProperties |
|
82 |
* the service properties |
|
83 |
* @param tMapFactory |
|
84 |
*/ |
|
85 |
public SolrIndexClient(final String format, final String layout, final String interpretation, final Map<String, String> serviceProperties, |
|
86 |
final SolrIndexQueryFactory indexQueryFactory, final QueryResponseFactory<QueryResponse> queryResponseFactory, |
|
87 |
final SolrTypeBasedCqlValueTransformerMapFactory tMapFactory) { |
|
88 |
this.format = format; |
|
89 |
this.layout = layout; |
|
90 |
this.interpretation = interpretation; |
|
91 |
this.serviceProperties = serviceProperties; |
|
92 |
this.solrIndexQueryFactory = indexQueryFactory; |
|
93 |
this.queryResponseFactory = queryResponseFactory; |
|
94 |
this.tMapFactory = tMapFactory; |
|
95 |
|
|
96 |
log.debug(String.format("Created a new instance of the index of type %s-%s-%s", format, layout, interpretation)); |
|
97 |
} |
|
98 |
|
|
99 |
/** |
|
100 |
* Do delete. |
|
101 |
* |
|
102 |
* @param query |
|
103 |
* the CQL query |
|
104 |
* @return true, if do delete |
|
105 |
* @throws IndexServiceException |
|
106 |
* the index service exception |
|
107 |
*/ |
|
108 |
@Override |
|
109 |
public long delete(final String query) throws IndexClientException { |
|
110 |
try { |
|
111 |
log.debug("delete by query: " + query); |
|
112 |
MetadataReference mdRef = new MetadataReference(getFormat(), getLayout(), getInterpretation()); |
|
113 |
SolrIndexQuery translatedQuery = (SolrIndexQuery) solrIndexQueryFactory.getIndexQuery(QueryLanguage.CQL, query, this, mdRef); |
|
114 |
String tquery = translatedQuery.getQuery(); |
|
115 |
translatedQuery.setQueryLimit(0); |
|
116 |
|
|
117 |
SolrIndexQueryResponse rsp = new SolrIndexQueryResponse(getClient().query(translatedQuery)); |
|
118 |
QueryResponseParser responseParser = queryResponseFactory.getQueryResponseParser(rsp, mdRef); |
|
119 |
long total = responseParser.getNumFound(); |
|
120 |
getClient().deleteByQuery(tquery); |
|
121 |
getClient().commit(); |
|
122 |
return total; |
|
123 |
} catch (Exception e) { |
|
124 |
throw new IndexClientException("unable to run delete by query: " + query, e); |
|
125 |
} |
|
126 |
} |
|
127 |
|
|
128 |
/** |
|
129 |
* {@inheritDoc} |
|
130 |
* |
Also available in: Unified diff
[maven-release-plugin] copy for tag dnet-index-client-3.0.0