mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
[CST-7756] porting of the script for notification of content subscription
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.content.crosswalk;
|
||||
|
||||
import static org.dspace.content.Item.ANY;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.factory.HandleServiceFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Creates a String to be sent as email body for subscriptions
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public class SubscriptionDsoMetadataForEmailCompose implements StreamDisseminationCrosswalk {
|
||||
|
||||
private List<String> metadata = new ArrayList<>();
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@Override
|
||||
public boolean canDisseminate(Context context, DSpaceObject dso) {
|
||||
return Objects.nonNull(dso) && dso.getType() == Constants.ITEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disseminate(Context context, DSpaceObject dso, OutputStream out) throws SQLException {
|
||||
if (dso.getType() == Constants.ITEM) {
|
||||
Item item = (Item) dso;
|
||||
PrintStream printStream = new PrintStream(out);
|
||||
for (String actualMetadata : metadata) {
|
||||
String[] splitted = actualMetadata.split("\\.");
|
||||
String qualifier = null;
|
||||
if (splitted.length == 1) {
|
||||
qualifier = splitted[2];
|
||||
}
|
||||
var metadataValue = itemService.getMetadataFirstValue(item, splitted[0], splitted[1], qualifier, ANY);
|
||||
printStream.print(metadataValue + " ");
|
||||
}
|
||||
String itemURL = HandleServiceFactory.getInstance()
|
||||
.getHandleService()
|
||||
.resolveToURL(context, item.getHandle());
|
||||
printStream.print(itemURL);
|
||||
printStream.print("\n");
|
||||
printStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMIMEType() {
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
public List<String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(List<String> metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
}
|
@@ -139,4 +139,23 @@ public class DiscoveryConfigurationService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of all DiscoveryConfiguration objects where key starts with prefixConfigurationName
|
||||
*
|
||||
* @param prefixConfigurationName string as prefix key
|
||||
*/
|
||||
public List<DiscoveryConfiguration> getDiscoveryConfigurationWithPrefixName(final String prefixConfigurationName) {
|
||||
List<DiscoveryConfiguration> discoveryConfigurationList = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(prefixConfigurationName)) {
|
||||
for (String key : map.keySet()) {
|
||||
if (key.equals(prefixConfigurationName) || key.startsWith(prefixConfigurationName)) {
|
||||
DiscoveryConfiguration config = map.get(key);
|
||||
discoveryConfigurationList.add(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return discoveryConfigurationList;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.discovery.configuration;
|
||||
|
||||
/**
|
||||
* This class extends {@link DiscoveryConfiguration} and add method for set parameters
|
||||
* to filter query list
|
||||
*
|
||||
* @author Danilo Di Nuzzo (danilo.dinuzzo at 4science.it)
|
||||
*/
|
||||
public class DiscoveryRelatedItemConfiguration extends DiscoveryConfiguration {}
|
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.discovery.configuration;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
*
|
||||
* Extension of {@link DiscoverySortFieldConfiguration} used to configure sorting
|
||||
* taking advantage of solr function feature.
|
||||
*
|
||||
* Order is evaluated by mean of function parameter value and passed in arguments as input.
|
||||
*
|
||||
* @author Corrado Lombardi (corrado.lombardi at 4science.it)
|
||||
*
|
||||
*/
|
||||
public class DiscoverySortFunctionConfiguration extends DiscoverySortFieldConfiguration {
|
||||
|
||||
public static final String SORT_FUNCTION = "sort_function";
|
||||
private String function;
|
||||
private List<String> arguments;
|
||||
private String id;
|
||||
|
||||
public void setFunction(final String function) {
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
public void setArguments(final List<String> arguments) {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return SORT_FUNCTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMetadataField() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the function to be used by solr to sort result
|
||||
* @param functionArgs variable arguments to be inserted in function
|
||||
* @return
|
||||
*/
|
||||
public String getFunction(final Serializable... functionArgs) {
|
||||
final String args = String.join(",", Optional.ofNullable(arguments).orElse(Collections.emptyList()));
|
||||
final String result = function + "(" + args + ")";
|
||||
return MessageFormat.format(result, functionArgs);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.apache.commons.lang.StringUtils.EMPTY;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.crosswalk.StreamDisseminationCrosswalk;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.Email;
|
||||
import org.dspace.core.I18nUtil;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.subscriptions.service.SubscriptionGenerator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Implementation class of SubscriptionGenerator
|
||||
* which will handle the logic of sending the emails
|
||||
* in case of content subscriptions
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class ContentGenerator implements SubscriptionGenerator<IndexableObject> {
|
||||
|
||||
private final Logger log = LogManager.getLogger(ContentGenerator.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Resource(name = "entityDissemination")
|
||||
private Map<String, StreamDisseminationCrosswalk> mapEntityDisseminatorProperty = new HashMap();
|
||||
|
||||
@Autowired
|
||||
private ItemService itemService;
|
||||
|
||||
@Override
|
||||
public void notifyForSubscriptions(Context context, EPerson ePerson,
|
||||
List<IndexableObject> indexableComm,
|
||||
List<IndexableObject> indexableColl,
|
||||
List<IndexableObject> indexableItems) {
|
||||
try {
|
||||
if (Objects.nonNull(ePerson)) {
|
||||
Locale supportedLocale = I18nUtil.getEPersonLocale(ePerson);
|
||||
Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "subscriptions_content"));
|
||||
email.addRecipient(ePerson.getEmail());
|
||||
email.addArgument(generateHtmlBodyMail(context, indexableComm));
|
||||
email.addArgument(generateHtmlBodyMail(context, indexableColl));
|
||||
email.addArgument(generateHtmlBodyMail(context, indexableItems));
|
||||
email.send();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// log this email error
|
||||
log.warn("Cannot email user eperson_id:" + ePerson.getID() + " eperson_email:" + ePerson.getEmail());
|
||||
}
|
||||
}
|
||||
|
||||
private String generateHtmlBodyMail(Context context, List<IndexableObject> indexableObjects) {
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write("\n".getBytes(UTF_8));
|
||||
if (indexableObjects.size() > 0) {
|
||||
for (IndexableObject indexableObject : indexableObjects) {
|
||||
out.write("\n".getBytes(UTF_8));
|
||||
Item item = (Item) indexableObject.getIndexedObject();
|
||||
var entityType = itemService.getEntityTypeLabel(item);
|
||||
mapEntityDisseminatorProperty.get(entityType).disseminate(context, item, out);
|
||||
}
|
||||
return out.toString();
|
||||
} else {
|
||||
out.write("No items".getBytes(UTF_8));
|
||||
}
|
||||
return out.toString();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.utils.DSpace;
|
||||
|
||||
/**
|
||||
* Implementation of {@link DSpaceRunnable} to find subscribed objects and send notification mails about them
|
||||
*
|
||||
* @author alba aliu
|
||||
*/
|
||||
public class SubscriptionEmailNotification
|
||||
extends DSpaceRunnable<SubscriptionEmailNotificationConfiguration<SubscriptionEmailNotification>> {
|
||||
|
||||
private Context context;
|
||||
private SubscriptionEmailNotificationService subscriptionEmailNotificationService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public SubscriptionEmailNotificationConfiguration<SubscriptionEmailNotification> getScriptConfiguration() {
|
||||
return new DSpace().getServiceManager().getServiceByName("subscription-send",
|
||||
SubscriptionEmailNotificationConfiguration.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() throws ParseException {
|
||||
this.subscriptionEmailNotificationService = new DSpace().getServiceManager().getServiceByName(
|
||||
SubscriptionEmailNotificationService.class.getName(), SubscriptionEmailNotificationService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalRun() throws Exception {
|
||||
assignCurrentUserInContext();
|
||||
assignSpecialGroupsInContext();
|
||||
String frequencyOption = commandLine.getOptionValue("f");
|
||||
if (StringUtils.isBlank(frequencyOption)) {
|
||||
throw new IllegalArgumentException("Option frequency f must be set");
|
||||
}
|
||||
if (!frequencyOption.equals("D") && !frequencyOption.equals("M") && !frequencyOption.equals("W")) {
|
||||
throw new IllegalArgumentException("Option f must be D, M or W");
|
||||
}
|
||||
subscriptionEmailNotificationService.perform(getContext(), handler, "content", frequencyOption);
|
||||
}
|
||||
|
||||
protected void assignCurrentUserInContext() throws SQLException {
|
||||
context = new Context();
|
||||
UUID uuid = getEpersonIdentifier();
|
||||
if (Objects.nonNull(uuid)) {
|
||||
EPerson ePerson = EPersonServiceFactory.getInstance().getEPersonService().find(context, uuid);
|
||||
context.setCurrentUser(ePerson);
|
||||
}
|
||||
}
|
||||
|
||||
private void assignSpecialGroupsInContext() throws SQLException {
|
||||
for (UUID uuid : handler.getSpecialGroups()) {
|
||||
context.setSpecialGroup(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public SubscriptionEmailNotificationService getSubscriptionEmailNotificationService() {
|
||||
return subscriptionEmailNotificationService;
|
||||
}
|
||||
|
||||
public void setSubscriptionEmailNotificationService(SubscriptionEmailNotificationService subscriptionNotifService) {
|
||||
this.subscriptionEmailNotificationService = subscriptionNotifService;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
/**
|
||||
* Extension of {@link SubscriptionEmailNotification} for CLI.
|
||||
*/
|
||||
public class SubscriptionEmailNotificationCli extends SubscriptionEmailNotification {
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
/**
|
||||
* Extension of {@link SubscriptionEmailNotificationCli} for CLI.
|
||||
*/
|
||||
public class SubscriptionEmailNotificationCliScriptConfiguration<T extends SubscriptionEmailNotificationCli>
|
||||
extends SubscriptionEmailNotificationConfiguration<T> {
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.dspace.authorize.AuthorizeServiceImpl;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.scripts.configuration.ScriptConfiguration;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Implementation of {@link DSpaceRunnable} to find subscribed objects and send notification mails about them
|
||||
*/
|
||||
public class SubscriptionEmailNotificationConfiguration<T
|
||||
extends SubscriptionEmailNotification> extends ScriptConfiguration<T> {
|
||||
|
||||
private Class<T> dspaceRunnableClass;
|
||||
|
||||
@Autowired
|
||||
private AuthorizeServiceImpl authorizeService;
|
||||
|
||||
@Override
|
||||
public boolean isAllowedToExecute(Context context) {
|
||||
try {
|
||||
return authorizeService.isAdmin(context);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("SQLException occurred when checking if the current user is an admin", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
if (Objects.isNull(options)) {
|
||||
Options options = new Options();
|
||||
options.addOption("f", "Frequency", true, "Subscription frequency. It can have value D, M or W");
|
||||
options.getOption("f").setRequired(true);
|
||||
super.options = options;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getDspaceRunnableClass() {
|
||||
return dspaceRunnableClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDspaceRunnableClass(Class<T> dspaceRunnableClass) {
|
||||
this.dspaceRunnableClass = dspaceRunnableClass;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,144 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.eperson.Subscription;
|
||||
import org.dspace.eperson.service.SubscribeService;
|
||||
import org.dspace.scripts.DSpaceRunnable;
|
||||
import org.dspace.scripts.handler.DSpaceRunnableHandler;
|
||||
import org.dspace.subscriptions.service.DSpaceObjectUpdates;
|
||||
import org.dspace.subscriptions.service.SubscriptionGenerator;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
|
||||
/**
|
||||
* Implementation of {@link DSpaceRunnable} to find subscribed objects and send notification mails about them
|
||||
*
|
||||
* @author alba aliu
|
||||
*/
|
||||
public class SubscriptionEmailNotificationService {
|
||||
|
||||
private static final Logger log = LogManager.getLogger(SubscriptionEmailNotification.class);
|
||||
|
||||
public static final List<String> FREQUENCIES = Arrays.asList("D", "W", "M");
|
||||
|
||||
private Map<String, DSpaceObjectUpdates> contentUpdates = new HashMap<>();
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map<String, SubscriptionGenerator> generators = new HashMap<>();
|
||||
@SuppressWarnings("rawtypes")
|
||||
private List<IndexableObject> communities = new ArrayList<>();
|
||||
@SuppressWarnings("rawtypes")
|
||||
private List<IndexableObject> collections = new ArrayList<>();
|
||||
@SuppressWarnings("rawtypes")
|
||||
private List<IndexableObject> items = new ArrayList<>();
|
||||
|
||||
private final SubscribeService subscribeService;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void perform(Context context, DSpaceRunnableHandler handler, String type, String frequency) {
|
||||
try {
|
||||
context.turnOffAuthorisationSystem();
|
||||
List<Subscription> subscriptionList = findAllSubscriptionsByTypeAndFrequency(context, type, frequency);
|
||||
// if content subscription
|
||||
// Here is verified if type is "content" Or "statistics" as them are configured
|
||||
if (type.equals(generators.keySet().toArray()[0])) {
|
||||
// the list of the person who has subscribed
|
||||
int iterator = 0;
|
||||
for (Subscription subscription : subscriptionList) {
|
||||
DSpaceObject dSpaceObject = getdSpaceObject(subscription);
|
||||
if (dSpaceObject instanceof Community) {
|
||||
communities.addAll(contentUpdates.get(Community.class.getSimpleName().toLowerCase(Locale.ROOT))
|
||||
.findUpdates(context, dSpaceObject, frequency));
|
||||
} else if (dSpaceObject instanceof Collection) {
|
||||
collections.addAll(contentUpdates.get(Collection.class.getSimpleName().toLowerCase(Locale.ROOT))
|
||||
.findUpdates(context, dSpaceObject, frequency));
|
||||
} else if (dSpaceObject instanceof Item) {
|
||||
items.addAll(contentUpdates.get(Item.class.getSimpleName().toLowerCase(Locale.ROOT))
|
||||
.findUpdates(context, dSpaceObject, frequency));
|
||||
}
|
||||
var ePerson = subscription.getePerson();
|
||||
if (iterator < subscriptionList.size() - 1) {
|
||||
if (ePerson.equals(subscriptionList.get(iterator + 1).getePerson())) {
|
||||
iterator++;
|
||||
continue;
|
||||
} else {
|
||||
generators.get(type)
|
||||
.notifyForSubscriptions(context, ePerson, communities, collections, items);
|
||||
communities.clear();
|
||||
collections.clear();
|
||||
items.clear();
|
||||
}
|
||||
} else {
|
||||
//in the end of the iteration
|
||||
generators.get(type).notifyForSubscriptions(context, ePerson, communities, collections, items);
|
||||
}
|
||||
iterator++;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Currently this type:" + type +
|
||||
" of subscription is not supported!");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
handler.handleException(e);
|
||||
context.abort();
|
||||
} finally {
|
||||
context.restoreAuthSystemState();
|
||||
}
|
||||
}
|
||||
|
||||
private DSpaceObject getdSpaceObject(Subscription subscription) {
|
||||
DSpaceObject dSpaceObject = subscription.getdSpaceObject();
|
||||
if (subscription.getdSpaceObject() instanceof HibernateProxy) {
|
||||
HibernateProxy hibernateProxy = (HibernateProxy) subscription.getdSpaceObject();
|
||||
LazyInitializer initializer = hibernateProxy.getHibernateLazyInitializer();
|
||||
dSpaceObject = (DSpaceObject) initializer.getImplementation();
|
||||
}
|
||||
return dSpaceObject;
|
||||
}
|
||||
|
||||
private List<Subscription> findAllSubscriptionsByTypeAndFrequency(Context context, String type, String frequency) {
|
||||
try {
|
||||
return this.subscribeService.findAllSubscriptionsByTypeAndFrequency(context, type, frequency)
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(s -> s.getePerson().getID()))
|
||||
.collect(Collectors.toList());
|
||||
} catch (SQLException e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return new ArrayList<Subscription>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public SubscriptionEmailNotificationService(SubscribeService subscribeService,
|
||||
Map<String, SubscriptionGenerator> generators,
|
||||
Map<String, DSpaceObjectUpdates> contentUpdates) {
|
||||
this.subscribeService = subscribeService;
|
||||
this.generators = generators;
|
||||
this.contentUpdates = contentUpdates;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions.dSpaceObjectsUpdates;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.subscriptions.service.DSpaceObjectUpdates;
|
||||
|
||||
/**
|
||||
* Class which will be used to find
|
||||
* all collection objects updated related with subscribed DSO
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public class CollectionsUpdates implements DSpaceObjectUpdates {
|
||||
|
||||
private final SearchService searchService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public List<IndexableObject> findUpdates(Context context, DSpaceObject dSpaceObject, String frequency)
|
||||
throws SearchServiceException {
|
||||
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||
discoverQuery.addFilterQueries("search.resourcetype:" + Item.class.getSimpleName());
|
||||
discoverQuery.addFilterQueries("location.coll:(" + dSpaceObject.getID() + ")");
|
||||
discoverQuery.addFilterQueries("lastModified_dt:" + findLastFrequency(frequency));
|
||||
DiscoverResult discoverResult = searchService.search(context, discoverQuery);
|
||||
return discoverResult.getIndexableObjects();
|
||||
}
|
||||
|
||||
public CollectionsUpdates(SearchService searchService) {
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions.dSpaceObjectsUpdates;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
import org.dspace.subscriptions.service.DSpaceObjectUpdates;
|
||||
|
||||
/**
|
||||
* Class which will be used to find
|
||||
* all community objects updated related with subscribed DSO
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public class CommunityUpdates implements DSpaceObjectUpdates {
|
||||
|
||||
private SearchService searchService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public List<IndexableObject> findUpdates(Context context, DSpaceObject dSpaceObject, String frequency)
|
||||
throws SearchServiceException {
|
||||
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||
discoverQuery.addFilterQueries("search.resourcetype:" + Item.class.getSimpleName());
|
||||
discoverQuery.addFilterQueries("location.comm:(" + dSpaceObject.getID() + ")");
|
||||
discoverQuery.addFilterQueries("lastModified_dt:" + this.findLastFrequency(frequency));
|
||||
DiscoverResult discoverResult = searchService.search(context, discoverQuery);
|
||||
return discoverResult.getIndexableObjects();
|
||||
}
|
||||
|
||||
public CommunityUpdates(SearchService searchService) {
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions.dSpaceObjectsUpdates;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.content.service.CommunityService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.DiscoverQuery;
|
||||
import org.dspace.discovery.DiscoverResult;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchService;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfiguration;
|
||||
import org.dspace.discovery.configuration.DiscoveryConfigurationService;
|
||||
import org.dspace.discovery.configuration.DiscoveryRelatedItemConfiguration;
|
||||
import org.dspace.discovery.configuration.DiscoverySortConfiguration;
|
||||
import org.dspace.discovery.configuration.DiscoverySortFieldConfiguration;
|
||||
import org.dspace.discovery.configuration.DiscoverySortFunctionConfiguration;
|
||||
import org.dspace.discovery.indexobject.IndexableCollection;
|
||||
import org.dspace.discovery.indexobject.IndexableCommunity;
|
||||
import org.dspace.discovery.indexobject.IndexableItem;
|
||||
import org.dspace.subscriptions.service.DSpaceObjectUpdates;
|
||||
|
||||
/**
|
||||
* Class which will be used to find
|
||||
* all item objects updated related with subscribed DSO
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public class ItemsUpdates implements DSpaceObjectUpdates {
|
||||
|
||||
private final Logger log = LogManager.getLogger(ItemsUpdates.class);
|
||||
|
||||
private final CollectionService collectionService;
|
||||
private final CommunityService communityService;
|
||||
private final ItemService itemService;
|
||||
private DiscoveryConfigurationService searchConfigurationService;
|
||||
private SearchService searchService;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public List<IndexableObject> findUpdates(Context context, DSpaceObject dSpaceObject, String frequency) {
|
||||
List<IndexableObject> list = new ArrayList<>();
|
||||
// entity type found
|
||||
String inverseRelationName = "RELATION." + itemService.getEntityTypeLabel((Item) dSpaceObject);
|
||||
List<DiscoveryConfiguration> discoveryConfigurationList =
|
||||
searchConfigurationService.getDiscoveryConfigurationWithPrefixName(inverseRelationName);
|
||||
DiscoverQuery discoverQuery = null;
|
||||
DiscoverResult searchResult = null;
|
||||
IndexableObject indexableObject = resolveScope(context, dSpaceObject.getID().toString());
|
||||
try {
|
||||
for (DiscoveryConfiguration discoveryConfiguration : discoveryConfigurationList) {
|
||||
discoverQuery = buildDiscoveryQuery(discoveryConfiguration, indexableObject);
|
||||
discoverQuery.addFilterQueries("lastModified_dt:" + this.findLastFrequency(frequency));
|
||||
searchResult = searchService.search(context, discoverQuery);
|
||||
list.addAll(searchResult.getIndexableObjects());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private IndexableObject<?, ?> resolveScope(Context context, String scope) {
|
||||
IndexableObject<?, ?> scopeObj = null;
|
||||
if (StringUtils.isBlank(scope)) {
|
||||
return scopeObj;
|
||||
}
|
||||
try {
|
||||
UUID uuid = UUID.fromString(scope);
|
||||
scopeObj = new IndexableCommunity(communityService.find(context, uuid));
|
||||
if (scopeObj.getIndexedObject() == null) {
|
||||
scopeObj = new IndexableCollection(collectionService.find(context, uuid));
|
||||
}
|
||||
if (scopeObj.getIndexedObject() == null) {
|
||||
scopeObj = new IndexableItem(itemService.find(context, uuid));
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.error("The given scope string " + trimToEmpty(scope) + " is not a UUID");
|
||||
} catch (SQLException e) {
|
||||
log.error("Unable to retrieve DSpace Object with ID " + trimToEmpty(scope) + " from the database");
|
||||
}
|
||||
return scopeObj;
|
||||
}
|
||||
|
||||
private DiscoverQuery buildDiscoveryQuery(DiscoveryConfiguration discoveryConfiguration, IndexableObject<?,?> scope)
|
||||
throws SQLException {
|
||||
DiscoverQuery discoverQuery = buildBaseQuery(discoveryConfiguration, scope);
|
||||
discoverQuery.addDSpaceObjectFilter(IndexableItem.TYPE);
|
||||
configureSorting(discoverQuery, discoveryConfiguration.getSearchSortConfiguration(), scope);
|
||||
return discoverQuery;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void configureSorting(DiscoverQuery queryArgs, DiscoverySortConfiguration searchSortConfiguration,
|
||||
final IndexableObject scope) {
|
||||
String sortBy = getDefaultSortField(searchSortConfiguration);
|
||||
String sortOrder = getDefaultSortDirection(searchSortConfiguration);
|
||||
//Update Discovery query
|
||||
DiscoverySortFieldConfiguration sortFieldConfiguration = searchSortConfiguration
|
||||
.getSortFieldConfiguration(sortBy);
|
||||
|
||||
if (Objects.nonNull(sortFieldConfiguration)) {
|
||||
String sortField;
|
||||
if (DiscoverySortFunctionConfiguration.SORT_FUNCTION.equals(sortFieldConfiguration.getType())) {
|
||||
sortField = MessageFormat.format(
|
||||
((DiscoverySortFunctionConfiguration) sortFieldConfiguration).getFunction(scope.getID()),
|
||||
scope.getID());
|
||||
} else {
|
||||
var type = sortFieldConfiguration.getType();
|
||||
var metadataField = sortFieldConfiguration.getMetadataField();
|
||||
sortField = searchService.toSortFieldIndex(metadataField, type);
|
||||
}
|
||||
|
||||
if ("asc".equalsIgnoreCase(sortOrder)) {
|
||||
queryArgs.setSortField(sortField, DiscoverQuery.SORT_ORDER.asc);
|
||||
} else if ("desc".equalsIgnoreCase(sortOrder)) {
|
||||
queryArgs.setSortField(sortField, DiscoverQuery.SORT_ORDER.desc);
|
||||
} else {
|
||||
log.error(sortOrder + " is not a valid sort order");
|
||||
}
|
||||
|
||||
} else {
|
||||
log.error(sortBy + " is not a valid sort field");
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultSortDirection(DiscoverySortConfiguration searchSortConfiguration) {
|
||||
return searchSortConfiguration.getSortFields().iterator().next().getDefaultSortOrder().toString();
|
||||
}
|
||||
|
||||
private String getDefaultSortField(DiscoverySortConfiguration searchSortConfiguration) {
|
||||
String sortBy;// Attempt to find the default one, if none found we use SCORE
|
||||
sortBy = "score";
|
||||
if (Objects.nonNull(searchSortConfiguration.getSortFields()) &&
|
||||
!searchSortConfiguration.getSortFields().isEmpty()) {
|
||||
DiscoverySortFieldConfiguration defaultSort = searchSortConfiguration.getSortFields().get(0);
|
||||
if (org.apache.commons.lang.StringUtils.isBlank(defaultSort.getMetadataField())) {
|
||||
return sortBy;
|
||||
}
|
||||
sortBy = defaultSort.getMetadataField();
|
||||
}
|
||||
return sortBy;
|
||||
}
|
||||
|
||||
private DiscoverQuery buildBaseQuery(DiscoveryConfiguration discoveryConfiguration, IndexableObject<?, ?> scope) {
|
||||
DiscoverQuery discoverQuery = new DiscoverQuery();
|
||||
if (Objects.isNull(discoveryConfiguration)) {
|
||||
return discoverQuery;
|
||||
}
|
||||
|
||||
discoverQuery.setDiscoveryConfigurationName(discoveryConfiguration.getId());
|
||||
List<String> filterQueries = discoveryConfiguration.getDefaultFilterQueries();
|
||||
|
||||
for (String filterQuery : filterQueries) {
|
||||
if (discoveryConfiguration instanceof DiscoveryRelatedItemConfiguration) {
|
||||
discoverQuery.addFilterQueries(MessageFormat.format(filterQuery, scope.getID()));
|
||||
} else {
|
||||
discoverQuery.addFilterQueries(filterQuery);
|
||||
}
|
||||
}
|
||||
return discoverQuery;
|
||||
}
|
||||
|
||||
public ItemsUpdates(CollectionService collectionService, CommunityService communityService, ItemService itemService,
|
||||
DiscoveryConfigurationService searchConfigurationService, SearchService searchService) {
|
||||
this.collectionService = collectionService;
|
||||
this.communityService = communityService;
|
||||
this.itemService = itemService;
|
||||
this.searchConfigurationService = searchConfigurationService;
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions.service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.discovery.IndexableObject;
|
||||
import org.dspace.discovery.SearchServiceException;
|
||||
|
||||
/**
|
||||
* Interface class which will be used to find all objects updated related with subscribed DSO
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public interface DSpaceObjectUpdates {
|
||||
|
||||
/**
|
||||
* Send an email to some addresses, concerning a Subscription, using a given dso.
|
||||
*
|
||||
* @param context current DSpace session.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public List<IndexableObject> findUpdates(Context context, DSpaceObject dSpaceObject, String frequency)
|
||||
throws SearchServiceException;
|
||||
|
||||
default String findLastFrequency(String frequency) {
|
||||
String startDate = "";
|
||||
String endDate = "";
|
||||
Calendar cal = Calendar.getInstance();
|
||||
// Full ISO 8601 is e.g.
|
||||
SimpleDateFormat fullIsoStart = new SimpleDateFormat("yyyy-MM-dd'T'00:00:00'Z'");
|
||||
SimpleDateFormat fullIsoEnd = new SimpleDateFormat("yyyy-MM-dd'T'23:59:59'Z'");
|
||||
switch (frequency) {
|
||||
case "D":
|
||||
cal.add(Calendar.DAY_OF_MONTH, -1);
|
||||
endDate = fullIsoEnd.format(cal.getTime());
|
||||
startDate = fullIsoStart.format(cal.getTime());
|
||||
break;
|
||||
case "M":
|
||||
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
|
||||
cal.add(Calendar.DAY_OF_MONTH, -dayOfMonth);
|
||||
endDate = fullIsoEnd.format(cal.getTime());
|
||||
cal.add(Calendar.MONTH, -1);
|
||||
cal.add(Calendar.DAY_OF_MONTH, 1);
|
||||
startDate = fullIsoStart.format(cal.getTime());
|
||||
break;
|
||||
case "W":
|
||||
cal.add(Calendar.DAY_OF_WEEK, -1);
|
||||
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
cal.add(Calendar.DAY_OF_WEEK, -dayOfWeek);
|
||||
endDate = fullIsoEnd.format(cal.getTime());
|
||||
cal.add(Calendar.DAY_OF_WEEK, -6);
|
||||
startDate = fullIsoStart.format(cal.getTime());
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return "[" + startDate + " TO " + endDate + "]";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.subscriptions.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
|
||||
/**
|
||||
* Interface Class which will be used to send email notifications to ePerson
|
||||
* containing information for all list of objects.
|
||||
*
|
||||
* @author Alba Aliu
|
||||
*/
|
||||
public interface SubscriptionGenerator<T> {
|
||||
|
||||
public void notifyForSubscriptions(Context c, EPerson ePerson, List<T> comm, List<T> coll, List<T> items);
|
||||
|
||||
}
|
@@ -80,4 +80,10 @@
|
||||
<property name="description" value="Batch Export to Simple Archive Format (SAF)"/>
|
||||
<property name="dspaceRunnableClass" value="org.dspace.app.itemexport.ItemExportCLI"/>
|
||||
</bean>
|
||||
|
||||
<bean id="subscription-send" class="org.dspace.subscriptions.SubscriptionEmailNotificationCliScriptConfiguration">
|
||||
<property name="description" value="Perform subscriptions send"/>
|
||||
<property name="dspaceRunnableClass" value="org.dspace.subscriptions.SubscriptionEmailNotificationCli"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<bean class="org.dspace.subscriptions.SubscriptionEmailNotificationService">
|
||||
<constructor-arg name="generators">
|
||||
<map>
|
||||
<entry key="content" value-ref="contentNotifyGenerator"/>
|
||||
</map>
|
||||
</constructor-arg>
|
||||
<constructor-arg name="contentUpdates">
|
||||
<map>
|
||||
<entry key="community" value-ref="communityUpdates"/>
|
||||
<entry key="collection" value-ref="collectionUpdates"/>
|
||||
<entry key="item" value-ref="itemUpdates"/>
|
||||
</map>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<util:map id="generators">
|
||||
<entry key="content" value-ref="contentNotifyGenerator"/>
|
||||
</util:map>
|
||||
|
||||
<bean id="contentNotifyGenerator" name="contentNotifyGenerator" class="org.dspace.subscriptions.ContentGenerator" />
|
||||
|
||||
<util:map id="contentUpdates">
|
||||
<entry key="community" value-ref="communityUpdates"/>
|
||||
<entry key="collection" value-ref="collectionUpdates"/>
|
||||
<entry key="item" value-ref="itemUpdates"/>
|
||||
</util:map>
|
||||
|
||||
<util:list id="generalMetadataEntity">
|
||||
<value>dc.title</value>
|
||||
</util:list>
|
||||
|
||||
<util:map id="entityDissemination">
|
||||
<entry key="Publication" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Person" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Journal" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="OrgUnit" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Dataset" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Patent" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Event" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Equipment" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="JournalVolume" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Project" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="PersonCv" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="JournalIssue" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
<entry key="Funding" value-ref="subscriptionDsoMetadataForEmailCompose"/>
|
||||
</util:map>
|
||||
|
||||
<bean class="org.dspace.content.crosswalk.SubscriptionDsoMetadataForEmailCompose" id="subscriptionDsoMetadataForEmailCompose">
|
||||
<property name="metadata" ref ="generalMetadataEntity"/>
|
||||
</bean>
|
||||
|
||||
<bean id="communityUpdates" name="communityUpdates" class="org.dspace.subscriptions.dSpaceObjectsUpdates.CommunityUpdates" />
|
||||
|
||||
<bean id="collectionUpdates" name="collectionUpdates" class="org.dspace.subscriptions.dSpaceObjectsUpdates.CollectionsUpdates" />
|
||||
|
||||
<bean id="itemUpdates" name="itemUpdates" class="org.dspace.subscriptions.dSpaceObjectsUpdates.ItemsUpdates" />
|
||||
|
||||
</beans>
|
Reference in New Issue
Block a user