Project

General

Profile

1
package eu.dnetlib.oai.sets;
2

    
3
import java.text.Normalizer;
4
import java.util.List;
5

    
6
import com.google.common.collect.Iterables;
7
import com.google.common.collect.Lists;
8
import com.mongodb.BasicDBObject;
9
import com.mongodb.BasicDBObjectBuilder;
10
import com.mongodb.DBObject;
11
import com.mongodb.MongoClient;
12
import com.mongodb.client.FindIterable;
13
import com.mongodb.client.MongoCollection;
14
import com.mongodb.client.model.Filters;
15
import com.mongodb.client.model.FindOneAndReplaceOptions;
16
import com.mongodb.client.model.FindOneAndUpdateOptions;
17
import com.mongodb.client.model.IndexOptions;
18
import eu.dnetlib.oai.info.SetInfo;
19
import org.apache.commons.lang3.StringEscapeUtils;
20
import org.apache.commons.lang3.StringUtils;
21
import org.bson.conversions.Bson;
22
import org.springframework.beans.factory.annotation.Autowired;
23

    
24
public class MongoSetCollection implements SetCollection {
25

    
26
	public static String DEFAULT_SET = "OTHER";
27

    
28
	@Autowired
29
	private MongoClient publisherMongoClient;
30
	private String setCollection = "sets";
31
	private String setCountCollection = "setsCount";
32

    
33
	public void ensureIndexes(final String dbName) {
34
		this.ensureIndexesOnSets(dbName);
35
		this.ensureIndexesOnCount(dbName);
36
	}
37

    
38
	@Override
39
	public List<SetInfo> getAllSets(final boolean enabledOnly, final String dbName) {
40
		FindIterable<DBObject> iter;
41
		if (!enabledOnly) {
42
			iter = this.getSetsCollection(dbName).find();
43
		} else {
44
			final Bson where = Filters.eq("enabled", true);
45
			iter = this.getSetsCollection(dbName).find(where);
46
		}
47
		return Lists.newArrayList(Iterables.transform(iter, dbObject ->  getSetFromDBObject(dbObject)));
48

    
49
	}
50

    
51
	@Override
52
	public boolean containSet(final String set, final String dbName) {
53
		final Bson query = Filters.eq("spec", set);
54
		return this.getSetsCollection(dbName).count(query) != 0;
55
	}
56

    
57
	@Override
58
	public boolean containEnabledSet(final String set, final String publisherDBName) {
59
		final Bson query = Filters.and(Filters.eq("spec", set), Filters.eq("enabled", true));
60
		return this.getSetsCollection(publisherDBName).count(query) != 0;
61
	}
62

    
63
	@Override
64
	public String getSetQuery(final String set, final String dbName) {
65
		final Bson query = Filters.eq("spec", set);
66
		final BasicDBObject returnField = new BasicDBObject("query", 1);
67
		final DBObject obj = this.getSetsCollection(dbName).find(query).projection(returnField).first();
68
		return (String) obj.get("query");
69
	}
70

    
71
	@Override
72
	public int count(final String setSpec, final String mdPrefix, final String dbName) {
73
		final Bson query = Filters.and(Filters.eq("spec", setSpec), Filters.eq("mdPrefix", mdPrefix));
74
		final BasicDBObject returnField = new BasicDBObject("count", 1);
75
		final DBObject obj = this.getSetsCountCollection(dbName).find(query).projection(returnField).first();
76
		if (obj == null) { return 0; }
77
		return (Integer) obj.get("count");
78
	}
79

    
80
	public void updateCounts(final String setSpec, final String mdPrefix, final int count, final String dbName) {
81
		final BasicDBObject countUpdate = new BasicDBObject("$set", new BasicDBObject("count", count));
82
		final Bson query = Filters.and(Filters.eq("spec", setSpec), Filters.eq("mdPrefix", mdPrefix));
83
		this.getSetsCountCollection(dbName).findOneAndUpdate(query, countUpdate, new FindOneAndUpdateOptions().upsert(true));
84
	}
85

    
86
	public void upsertSet(final SetInfo setInfo, final boolean fromConfiguration, final String dbName) {
87
		final DBObject obj = this.getObjectFromSet(setInfo);
88
		obj.put("fromConfiguration", fromConfiguration);
89
		this.getSetsCollection(dbName).findOneAndReplace(Filters.eq("spec", setInfo.getSetSpec()), obj, new FindOneAndReplaceOptions().upsert(true));
90
	}
91

    
92
	public String normalizeSetSpec(final String setName) {
93
		String s = StringEscapeUtils.unescapeXml(setName);
94
		s = Normalizer.normalize(s, Normalizer.Form.NFD);
95
		// replace spaces with underscores
96
		s = s.replaceAll(" ", "_");
97
		// remove tilde, dots... over letters
98
		s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}&&[^-_]]", "");
99
		// change punctuation into an underscore
100
		s = s.replaceAll("[\\p{Punct}&&[^-_]]", "_");
101
		// remove all non-word characters
102
		s = s.replaceAll("[\\W&&[^-_]]", "");
103
		// Avoiding set '___' generated when we have "strange" set names such as those in cyrillic/ukrain
104
		// strips _ from the beginning and the end
105
		String stripped = StringUtils.strip(s, "_ ");
106
		if (StringUtils.isBlank(stripped)) {
107
			stripped = DEFAULT_SET;
108
		}
109
		return stripped;
110
	}
111

    
112
	public List<SetInfo> getConfiguredSets(final String dbName) {
113
		final Bson query = Filters.eq("fromConfiguration", true);
114
		return this.findSets(query, dbName);
115
	}
116

    
117
	public List<SetInfo> getSetsFromData(final String dbName) {
118
		final Bson query = Filters.eq("fromConfiguration", false);
119
		return this.findSets(query, dbName);
120
	}
121

    
122
	public void dropOAISets(final String dbName) {
123
		this.getSetsCountCollection(dbName).drop();
124
		this.getSetsCollection(dbName).drop();
125
	}
126

    
127
	public void dropSet(final String dbName, final String setSpec) {
128
		final Bson query = Filters.eq("spec", normalizeSetSpec(setSpec));
129
		this.getSetsCollection(dbName).deleteMany(query);
130
		this.getSetsCountCollection(dbName).deleteMany(query);
131
	}
132

    
133
	public void dropConfigurationSets(final String dbName) {
134
		this.getSetsCollection(dbName).deleteMany(Filters.eq("fromConfiguration", true));
135
	}
136

    
137
	protected List<SetInfo> findSets(final Bson query, final String dbName) {
138
		final FindIterable<DBObject> sets = this.getSetsCollection(dbName).find(query);
139
		final List<SetInfo> res = Lists.newArrayList();
140
		for (final DBObject obj : sets) {
141
			res.add(this.getSetFromDBObject(obj));
142
		}
143
		return res;
144
	}
145

    
146
	private SetInfo getSetFromDBObject(final DBObject obj) {
147
		final SetInfo setInfo = new SetInfo();
148
		setInfo.setEnabled((Boolean) obj.get("enabled"));
149
		setInfo.setQuery((String) obj.get("query"));
150
		setInfo.setSetDescription((String) obj.get("description"));
151
		setInfo.setSetName((String) obj.get("name"));
152
		setInfo.setSetSpec((String) obj.get("spec"));
153
		return setInfo;
154
	}
155

    
156
	private DBObject getObjectFromSet(final SetInfo s) {
157
		final DBObject obj = BasicDBObjectBuilder.start("spec", s.getSetSpec()).add("name", s.getSetName()).add("description", s.getSetDescription())
158
				.add("query", s.getQuery()).add("enabled", s.isEnabled()).get();
159
		return obj;
160
	}
161

    
162
	private void ensureIndexesOnSets(final String dbName) {
163
		this.getSetsCollection(dbName).createIndex(new BasicDBObject("spec", 1), new IndexOptions().background(true));
164
		this.getSetsCollection(dbName).createIndex(new BasicDBObject("fromConfiguration", 1), new IndexOptions().background(true));
165
	}
166

    
167
	private void ensureIndexesOnCount(final String dbName) {
168
		final BasicDBObject index = (BasicDBObject) BasicDBObjectBuilder.start("spec", 1).add("mdPrefix", 1).get();
169
		this.getSetsCountCollection(dbName).createIndex(index, new IndexOptions().background(true));
170
	}
171

    
172
	public MongoCollection<DBObject> getSetsCollection(final String dbName) {
173
		return this.getCollection(this.setCollection, dbName);
174
	}
175

    
176
	public MongoCollection<DBObject> getSetsCountCollection(final String dbName) {
177
		return this.getCollection(this.setCountCollection, dbName);
178
	}
179

    
180
	private MongoCollection<DBObject> getCollection(final String collectionName, final String dbName) {
181
		return this.publisherMongoClient.getDatabase(dbName).getCollection(collectionName, DBObject.class);
182
	}
183

    
184
	public String getSetCollection() {
185
		return this.setCollection;
186
	}
187

    
188
	public void setSetCollection(final String setCollection) {
189
		this.setCollection = setCollection;
190
	}
191

    
192
	public String getSetCountCollection() {
193
		return this.setCountCollection;
194
	}
195

    
196
	public void setSetCountCollection(final String setCountCollection) {
197
		this.setCountCollection = setCountCollection;
198
	}
199

    
200
	public MongoClient getPublisherMongoClient() {
201
		return this.publisherMongoClient;
202
	}
203

    
204
	public void setPublisherMongoClient(final MongoClient publisherMongoClient) {
205
		this.publisherMongoClient = publisherMongoClient;
206
	}
207

    
208
}
(1-1/3)