Skip to content

Commit b2cf38a

Browse files
committed
[DURACOM-427] changes from DSC-27, DSC-1459 and DSC-1626
1 parent 52c4854 commit b2cf38a

31 files changed

+3103
-39
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
9+
package org.dspace.authority;
10+
11+
import java.util.Arrays;
12+
import java.util.List;
13+
import java.util.Objects;
14+
import java.util.stream.Collectors;
15+
import java.util.stream.Stream;
16+
17+
import org.apache.commons.lang3.StringUtils;
18+
import org.dspace.app.itemupdate.MetadataUtilities;
19+
import org.dspace.app.util.DCInput;
20+
import org.dspace.app.util.DCInputsReader;
21+
import org.dspace.app.util.DCInputsReaderException;
22+
import org.dspace.content.Collection;
23+
import org.dspace.content.Item;
24+
import org.dspace.content.MetadataValue;
25+
import org.dspace.content.authority.Choices;
26+
import org.dspace.content.factory.ContentServiceFactory;
27+
import org.dspace.content.service.ItemService;
28+
import org.dspace.core.Context;
29+
import org.dspace.event.Consumer;
30+
import org.dspace.event.Event;
31+
32+
/**
33+
*
34+
* @author Stefano Maffei(stefano.maffei at 4science.com)
35+
*
36+
*/
37+
public class AuthorityLinkConsumer implements Consumer {
38+
39+
public static final String CONSUMER_NAME = "authoritylink";
40+
41+
private ItemService itemService;
42+
43+
@Override
44+
@SuppressWarnings("unchecked")
45+
public void initialize() throws Exception {
46+
itemService = ContentServiceFactory.getInstance().getItemService();
47+
}
48+
49+
@Override
50+
public void finish(Context context) throws Exception {
51+
52+
}
53+
54+
@Override
55+
public void consume(Context context, Event event) throws Exception {
56+
57+
Item item = (Item) event.getSubject(context);
58+
if (item == null || !item.isArchived()) {
59+
return;
60+
}
61+
62+
context.turnOffAuthorisationSystem();
63+
try {
64+
consumeItem(context, item);
65+
} finally {
66+
context.restoreAuthSystemState();
67+
}
68+
69+
}
70+
71+
private void consumeItem(Context context, Item item) throws Exception {
72+
List<String> linkMetadata = getLinkMetadata(context, item);
73+
List<MetadataValue> metadataValues = linkMetadata.stream()
74+
.flatMap((String metadata) -> {
75+
String[] splittedMetadata;
76+
try {
77+
splittedMetadata = MetadataUtilities.parseCompoundForm(metadata);
78+
return itemService.getMetadata(item, splittedMetadata[0], splittedMetadata[1],
79+
splittedMetadata.length > 2 ? splittedMetadata[2] : null, Item.ANY).stream();
80+
} catch (Exception e) {
81+
return Stream.of();
82+
}
83+
84+
})
85+
.filter(Objects::nonNull)
86+
.collect(Collectors.toList());
87+
metadataValues
88+
.stream()
89+
.filter(metadataVal -> StringUtils.isBlank(metadataVal.getAuthority()))
90+
.forEach(metadataVal -> {
91+
metadataVal.setAuthority(metadataVal.getValue());
92+
metadataVal.setConfidence(Choices.CF_ACCEPTED);
93+
});
94+
metadataValues
95+
.stream()
96+
.filter(metadataVal -> StringUtils.isBlank(metadataVal.getValue()))
97+
.forEach(metadataVal -> {
98+
metadataVal.setValue(metadataVal.getAuthority());
99+
metadataVal.setConfidence(Choices.CF_ACCEPTED);
100+
});
101+
102+
}
103+
104+
private List<String> getLinkMetadata(Context context, Item item) throws DCInputsReaderException {
105+
List<DCInput> inputs = getAllInputsByCollection(item.getOwningCollection());
106+
return inputs.stream()
107+
.filter(input -> input.getInputType().equalsIgnoreCase("link"))
108+
.map(DCInput::getFieldName)
109+
.collect(Collectors.toList());
110+
}
111+
112+
private List<DCInput> getAllInputsByCollection(Collection collection) throws DCInputsReaderException {
113+
DCInputsReader inputsReader = new DCInputsReader();
114+
return inputsReader.getInputsByCollection(collection).stream()
115+
.flatMap(dcInputSet -> Arrays.stream(dcInputSet.getFields()))
116+
.flatMap(dcInputs -> Arrays.stream(dcInputs))
117+
.collect(Collectors.toList());
118+
}
119+
120+
@Override
121+
public void end(Context context) throws Exception {
122+
}
123+
124+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
package org.dspace.content.dao;
9+
10+
import java.sql.SQLException;
11+
import java.util.UUID;
12+
13+
import org.dspace.core.Context;
14+
15+
public interface ItemForMetadataEnhancementUpdateDAO {
16+
17+
/**
18+
* Add to the metadata_enhancement_update table queue an entry of each items
19+
* that is potentially affected by the update of the Item with the specified
20+
* uuid. The items potentially affected are the one that have the provided uuid
21+
* as value of a cris.virtualsource.* metadata
22+
*
23+
* @param context the DSpace Context object
24+
* @param uuid the uuid of the updated item
25+
* @return the number of affected items scheduled for update
26+
* @throws SQLException if a problem with the database occurs
27+
*/
28+
int saveAffectedItemsForUpdate(Context context, UUID uuid);
29+
30+
/**
31+
* Remove from the metadata_enhancement_update table queue the entry if any
32+
* related to the specified id in older than the current date
33+
*
34+
* @param context the DSpace Context object
35+
* @param itemToRemove the uuid of the processed item
36+
* @throws SQLException if a problem with the database occurs
37+
*/
38+
void removeItemForUpdate(Context context, UUID itemToRemove);
39+
40+
/**
41+
* Extract and remove from the table the first uuid to process from the
42+
* itemupdate_metadata_enhancement table ordered by date queued asc (older
43+
* first)
44+
*
45+
* @param context
46+
* @return
47+
*/
48+
UUID pollItemToUpdate(Context context);
49+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
package org.dspace.content.dao.impl;
9+
10+
import java.sql.SQLException;
11+
import java.util.UUID;
12+
13+
import org.dspace.content.MetadataSchema;
14+
import org.dspace.content.dao.ItemForMetadataEnhancementUpdateDAO;
15+
import org.dspace.content.factory.ContentServiceFactory;
16+
import org.dspace.content.service.MetadataSchemaService;
17+
import org.dspace.core.Context;
18+
import org.dspace.core.DBConnection;
19+
import org.dspace.services.ConfigurationService;
20+
import org.dspace.utils.DSpace;
21+
import org.hibernate.Session;
22+
import org.hibernate.query.NativeQuery;
23+
import org.springframework.beans.factory.annotation.Autowired;
24+
25+
/**
26+
* Hibernate implementation of the Database Access Object interface class for
27+
* the ItemForMetadataEnhancementUpdate object. This class is responsible for
28+
* all database calls for the ItemForMetadataEnhancementUpdate object and is
29+
* autowired by spring This class should never be accessed directly.
30+
*/
31+
public class ItemForMetadataEnhancementUpdateDAOImpl implements ItemForMetadataEnhancementUpdateDAO {
32+
@Autowired
33+
ConfigurationService configurationService;
34+
35+
@Override
36+
public void removeItemForUpdate(Context context, UUID itemToRemove) {
37+
try {
38+
Session session = getHibernateSession();
39+
String sql = "DELETE FROM itemupdate_metadata_enhancement WHERE uuid = :uuid";
40+
NativeQuery<?> query = session.createNativeQuery(sql);
41+
query.setParameter("uuid", itemToRemove);
42+
query.executeUpdate();
43+
} catch (Exception e) {
44+
throw new RuntimeException(e);
45+
}
46+
47+
}
48+
49+
@Override
50+
public UUID pollItemToUpdate(Context context) {
51+
try {
52+
Session session = getHibernateSession();
53+
String sql = "SELECT cast(uuid as varchar) FROM itemupdate_metadata_enhancement"
54+
+ " ORDER BY date_queued ASC LIMIT 1";
55+
NativeQuery<?> query = session.createNativeQuery(sql);
56+
Object uuidObj = query.uniqueResult();
57+
if (uuidObj != null) {
58+
UUID uuid;
59+
if (uuidObj instanceof String) {
60+
uuid = (UUID) UUID.fromString((String) uuidObj);
61+
} else {
62+
throw new RuntimeException("Unexpected result type from the database " + uuidObj);
63+
}
64+
removeItemForUpdate(context, uuid);
65+
return uuid;
66+
} else {
67+
return null;
68+
}
69+
} catch (Exception e) {
70+
throw new RuntimeException(e);
71+
}
72+
73+
}
74+
75+
@Override
76+
public int saveAffectedItemsForUpdate(Context context, UUID uuid) {
77+
try {
78+
Session session = getHibernateSession();
79+
MetadataSchemaService schemaService = ContentServiceFactory.getInstance().getMetadataSchemaService();
80+
MetadataSchema schema = schemaService.find(context, "cris");
81+
String sqlInsertOrUpdate;
82+
if ("org.h2.Driver".equals(configurationService.getProperty("db.driver"))) {
83+
// H2 doesn't support the INSERT OR UPDATE statement so let's do in two steps
84+
// update queued date for records already in the queue
85+
String sqlUpdate = "UPDATE itemupdate_metadata_enhancement iue " +
86+
"SET date_queued = CURRENT_TIMESTAMP " +
87+
"WHERE EXISTS ( " +
88+
" SELECT 1 " +
89+
" FROM metadatavalue mv " +
90+
" JOIN metadatafieldregistry mfr ON mv.metadata_field_id = mfr.metadata_field_id " +
91+
" WHERE mv.dspace_object_id = iue.uuid " +
92+
" AND mfr.metadata_schema_id = :schema " +
93+
" AND mfr.element = 'virtualsource' " +
94+
" AND SUBSTRING(mv.text_value,1,36) = :uuid " +
95+
")";
96+
String sqlInsert =
97+
"INSERT INTO itemupdate_metadata_enhancement (uuid, date_queued) " +
98+
"SELECT DISTINCT mv.dspace_object_id, CURRENT_TIMESTAMP " +
99+
"FROM metadatavalue mv " +
100+
"JOIN metadatafieldregistry mfr ON mv.metadata_field_id = mfr.metadata_field_id " +
101+
"LEFT JOIN itemupdate_metadata_enhancement iue ON mv.dspace_object_id = iue.uuid " +
102+
"WHERE mfr.metadata_schema_id = :schema " +
103+
"AND mfr.element = 'virtualsource' " +
104+
"AND SUBSTRING(mv.text_value,1,36) = :uuid " +
105+
"AND iue.uuid IS NULL";
106+
NativeQuery<?> queryUpdate = session.createNativeQuery(sqlUpdate);
107+
queryUpdate.setParameter("uuid", uuid.toString());
108+
queryUpdate.setParameter("schema", schema.getID());
109+
queryUpdate.executeUpdate();
110+
NativeQuery<?> queryInsert = session.createNativeQuery(sqlInsert);
111+
queryInsert.setParameter("uuid", uuid.toString());
112+
queryInsert.setParameter("schema", schema.getID());
113+
return queryInsert.executeUpdate();
114+
} else {
115+
sqlInsertOrUpdate = "INSERT INTO itemupdate_metadata_enhancement (uuid, date_queued)" +
116+
"SELECT DISTINCT mv.dspace_object_id, CURRENT_TIMESTAMP " +
117+
"FROM metadatavalue mv " +
118+
"JOIN metadatafieldregistry mfr ON mv.metadata_field_id = mfr.metadata_field_id " +
119+
"WHERE mfr.metadata_schema_id = :schema " +
120+
"AND mfr.element = 'virtualsource' " +
121+
"AND SUBSTRING(mv.text_value,1,36) = :uuid " +
122+
"ON CONFLICT (uuid) DO UPDATE " +
123+
"SET date_queued = EXCLUDED.date_queued";
124+
NativeQuery<?> queryInsertOrUpdate = session.createNativeQuery(sqlInsertOrUpdate);
125+
queryInsertOrUpdate.setParameter("uuid", uuid.toString());
126+
queryInsertOrUpdate.setParameter("schema", schema.getID());
127+
return queryInsertOrUpdate.executeUpdate();
128+
}
129+
} catch (Exception e) {
130+
throw new RuntimeException(e);
131+
}
132+
}
133+
134+
/**
135+
* The Hibernate Session used in the current thread
136+
*
137+
* @return the current Session.
138+
* @throws SQLException
139+
*/
140+
private Session getHibernateSession() throws SQLException {
141+
DBConnection dbConnection = new DSpace().getServiceManager().getServiceByName(null, DBConnection.class);
142+
return ((Session) dbConnection.getSession());
143+
}
144+
145+
public UUID ConvertByteArrayToUUID(byte[] bytea) {
146+
long mostSigBits = 0;
147+
long leastSigBits = 0;
148+
for (int i = 0; i < 8; i++) {
149+
mostSigBits = (mostSigBits << 8) | (bytea[i] & 0xff);
150+
leastSigBits = (leastSigBits << 8) | (bytea[i + 8] & 0xff);
151+
}
152+
153+
UUID uuid = new UUID(mostSigBits, leastSigBits);
154+
return uuid;
155+
}
156+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
package org.dspace.content.enhancer;
9+
10+
/**
11+
* Abstract implementation of {@link ItemEnhancer} that provide common structure
12+
* for all the item enhancers.
13+
*
14+
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
15+
*
16+
*/
17+
public abstract class AbstractItemEnhancer implements ItemEnhancer {
18+
19+
private String virtualQualifier;
20+
21+
public String getVirtualQualifier() {
22+
return virtualQualifier;
23+
}
24+
25+
public void setVirtualQualifier(String virtualQualifier) {
26+
this.virtualQualifier = virtualQualifier;
27+
}
28+
29+
protected String getVirtualMetadataField() {
30+
return VIRTUAL_METADATA_SCHEMA + "." + VIRTUAL_METADATA_ELEMENT + "." + virtualQualifier;
31+
}
32+
33+
protected String getVirtualSourceMetadataField() {
34+
return VIRTUAL_METADATA_SCHEMA + "." + VIRTUAL_SOURCE_METADATA_ELEMENT + "." + virtualQualifier;
35+
}
36+
37+
}

0 commit comments

Comments
 (0)