Project

General

Profile

1
package eu.dnetlib.oai.sets;
2

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

    
6
import org.apache.commons.lang3.StringEscapeUtils;
7
import org.apache.commons.lang3.StringUtils;
8
import org.bson.conversions.Bson;
9
import org.springframework.beans.factory.annotation.Autowired;
10

    
11
import com.google.common.base.Function;
12
import com.google.common.collect.Iterables;
13
import com.google.common.collect.Lists;
14
import com.mongodb.BasicDBObject;
15
import com.mongodb.BasicDBObjectBuilder;
16
import com.mongodb.DBObject;
17
import com.mongodb.MongoClient;
18
import com.mongodb.client.FindIterable;
19
import com.mongodb.client.MongoCollection;
20
import com.mongodb.client.model.Filters;
21
import com.mongodb.client.model.FindOneAndReplaceOptions;
22
import com.mongodb.client.model.FindOneAndUpdateOptions;
23
import com.mongodb.client.model.IndexOptions;
24

    
25
import eu.dnetlib.oai.info.SetInfo;
26

    
27
public class MongoSetCollection implements SetCollection {
28

    
29
	public static String DEFAULT_SET = "OTHER";
30

    
31
	@Autowired
32
	private MongoClient publisherMongoClient;
33
	private String setCollection = "sets";
34
	private String setCountCollection = "setsCount";
35

    
36
	public void ensureIndexes(final String dbName) {
37
		this.ensureIndexesOnSets(dbName);
38
		this.ensureIndexesOnCount(dbName);
39
	}
40

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

    
52
			@Override
53
			public SetInfo apply(final DBObject dbObject) {
54
				return getSetFromDBObject(dbObject);
55
			}
56
		}));
57
	}
58

    
59
	@Override
60
	public boolean containSet(final String set, final String dbName) {
61
		final Bson query = Filters.eq("spec", set);
62
		return this.getSetsCollection(dbName).count(query) != 0;
63
	}
64

    
65
	@Override
66
	public boolean containEnabledSet(final String set, final String publisherDBName) {
67
		final Bson query = Filters.and(Filters.eq("spec", set), Filters.eq("enabled", true));
68
		return this.getSetsCollection(publisherDBName).count(query) != 0;
69
	}
70

    
71
	@Override
72
	public String getSetQuery(final String set, final String dbName) {
73
		final Bson query = Filters.eq("spec", set);
74
		final BasicDBObject returnField = new BasicDBObject("query", 1);
75
		final DBObject obj = this.getSetsCollection(dbName).find(query).projection(returnField).first();
76
		return (String) obj.get("query");
77
	}
78

    
79
	@Override
80
	public int count(final String setSpec, final String mdPrefix, final String dbName) {
81
		final Bson query = Filters.and(Filters.eq("spec", setSpec), Filters.eq("mdPrefix", mdPrefix));
82
		final BasicDBObject returnField = new BasicDBObject("count", 1);
83
		final DBObject obj = this.getSetsCountCollection(dbName).find(query).projection(returnField).first();
84
		if (obj == null) { return 0; }
85
		return (Integer) obj.get("count");
86
	}
87

    
88
	public void updateCounts(final String setSpec, final String mdPrefix, final int count, final String dbName) {
89
		final BasicDBObject countUpdate = new BasicDBObject("$set", new BasicDBObject("count", count));
90
		final Bson query = Filters.and(Filters.eq("spec", setSpec), Filters.eq("mdPrefix", mdPrefix));
91
		this.getSetsCountCollection(dbName).findOneAndUpdate(query, countUpdate, new FindOneAndUpdateOptions().upsert(true));
92
	}
93

    
94
	public void upsertSet(final SetInfo setInfo, final boolean fromConfiguration, final String dbName) {
95
		final DBObject obj = this.getObjectFromSet(setInfo);
96
		obj.put("fromConfiguration", fromConfiguration);
97
		this.getSetsCollection(dbName).findOneAndReplace(Filters.eq("spec", setInfo.getSetSpec()), obj, new FindOneAndReplaceOptions().upsert(true));
98
	}
99

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

    
120
	public List<SetInfo> getConfiguredSets(final String dbName) {
121
		final Bson query = Filters.eq("fromConfiguration", true);
122
		return this.findSets(query, dbName);
123
	}
124

    
125
	public List<SetInfo> getSetsFromData(final String dbName) {
126
		final Bson query = Filters.eq("fromConfiguration", false);
127
		return this.findSets(query, dbName);
128
	}
129

    
130
	public void dropOAISets(final String dbName) {
131
		this.getSetsCountCollection(dbName).drop();
132
		this.getSetsCollection(dbName).drop();
133
	}
134

    
135
	public void dropSet(final String dbName, final String setSpec) {
136
		final Bson query = Filters.eq("spec", setSpec);
137
		this.getSetsCollection(dbName).deleteMany(query);
138
		this.getSetsCountCollection(dbName).deleteMany(query);
139
	}
140

    
141
//	public void dropConfigurationSets(final String dbName) {
142
//		this.getSetsCollection(dbName).deleteMany(Filters.eq("fromConfiguration", true));
143
//	}
144

    
145
	protected List<SetInfo> findSets(final Bson query, final String dbName) {
146
		final FindIterable<DBObject> sets = this.getSetsCollection(dbName).find(query);
147
		final List<SetInfo> res = Lists.newArrayList();
148
		for (final DBObject obj : sets) {
149
			res.add(this.getSetFromDBObject(obj));
150
		}
151
		return res;
152
	}
153

    
154
	private SetInfo getSetFromDBObject(final DBObject obj) {
155
		final SetInfo setInfo = new SetInfo();
156
		setInfo.setEnabled((Boolean) obj.get("enabled"));
157
		setInfo.setQuery((String) obj.get("query"));
158
		setInfo.setSetDescription((String) obj.get("description"));
159
		setInfo.setSetName((String) obj.get("name"));
160
		setInfo.setSetSpec((String) obj.get("spec"));
161
		return setInfo;
162
	}
163

    
164
	private DBObject getObjectFromSet(final SetInfo s) {
165
		final DBObject obj = BasicDBObjectBuilder.start("spec", s.getSetSpec()).add("name", s.getSetName()).add("description", s.getSetDescription())
166
				.add("query", s.getQuery()).add("enabled", s.isEnabled()).get();
167
		return obj;
168
	}
169

    
170
	private void ensureIndexesOnSets(final String dbName) {
171
		this.getSetsCollection(dbName).createIndex(new BasicDBObject("spec", 1), new IndexOptions().background(true));
172
		this.getSetsCollection(dbName).createIndex(new BasicDBObject("fromConfiguration", 1), new IndexOptions().background(true));
173
	}
174

    
175
	private void ensureIndexesOnCount(final String dbName) {
176
		final BasicDBObject index = (BasicDBObject) BasicDBObjectBuilder.start("spec", 1).add("mdPrefix", 1).get();
177
		this.getSetsCountCollection(dbName).createIndex(index, new IndexOptions().background(true));
178
	}
179

    
180
	public MongoCollection<DBObject> getSetsCollection(final String dbName) {
181
		return this.getCollection(this.setCollection, dbName);
182
	}
183

    
184
	public MongoCollection<DBObject> getSetsCountCollection(final String dbName) {
185
		return this.getCollection(this.setCountCollection, dbName);
186
	}
187

    
188
	private MongoCollection<DBObject> getCollection(final String collectionName, final String dbName) {
189
		return this.publisherMongoClient.getDatabase(dbName).getCollection(collectionName, DBObject.class);
190
	}
191

    
192
	public String getSetCollection() {
193
		return this.setCollection;
194
	}
195

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

    
200
	public String getSetCountCollection() {
201
		return this.setCountCollection;
202
	}
203

    
204
	public void setSetCountCollection(final String setCountCollection) {
205
		this.setCountCollection = setCountCollection;
206
	}
207

    
208
	public MongoClient getPublisherMongoClient() {
209
		return this.publisherMongoClient;
210
	}
211

    
212
	public void setPublisherMongoClient(final MongoClient publisherMongoClient) {
213
		this.publisherMongoClient = publisherMongoClient;
214
	}
215

    
216
}
(1-1/2)