diff src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java @ 10:a50cf11e5178

Rewrite LGDataverse completely upgrading to dataverse4.0
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Tue, 08 Sep 2015 17:00:21 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/java/edu/harvard/iq/dataverse/EjbDataverseEngine.java	Tue Sep 08 17:00:21 2015 +0200
@@ -0,0 +1,381 @@
+package edu.harvard.iq.dataverse;
+
+import edu.harvard.iq.dataverse.actionlogging.ActionLogRecord;
+import edu.harvard.iq.dataverse.actionlogging.ActionLogServiceBean;
+import edu.harvard.iq.dataverse.authorization.AuthenticationServiceBean;
+import edu.harvard.iq.dataverse.authorization.providers.builtin.BuiltinUserServiceBean;
+import edu.harvard.iq.dataverse.engine.DataverseEngine;
+import edu.harvard.iq.dataverse.authorization.Permission;
+import edu.harvard.iq.dataverse.authorization.groups.impl.explicit.ExplicitGroupServiceBean;
+import edu.harvard.iq.dataverse.authorization.users.User;
+import edu.harvard.iq.dataverse.engine.command.Command;
+import edu.harvard.iq.dataverse.engine.command.CommandContext;
+import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
+import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
+import java.util.Map;
+import java.util.Set;
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.inject.Named;
+
+import edu.harvard.iq.dataverse.search.SolrIndexServiceBean;
+import edu.harvard.iq.dataverse.search.savedsearch.SavedSearchServiceBean;
+import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
+import java.util.EnumSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.ejb.EJBException;
+import javax.ejb.TransactionAttribute;
+import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+
+/**
+ * An EJB capable of executing {@link Command}s in a JEE environment.
+ *
+ * @author michael
+ */
+@Stateless
+@Named
+public class EjbDataverseEngine {
+    private static final Logger logger = Logger.getLogger(EjbDataverseEngine.class.getCanonicalName());
+    
+    @EJB
+    DatasetServiceBean datasetService;
+
+    @EJB
+    DataverseServiceBean dataverseService;
+
+    @EJB
+    DataverseRoleServiceBean roleService;
+
+    @EJB
+    DataverseRoleServiceBean rolesService;
+
+    @EJB
+    BuiltinUserServiceBean usersService;
+
+    @EJB
+    IndexServiceBean indexService;
+
+    @EJB
+    SolrIndexServiceBean solrIndexService;
+
+    @EJB
+    SearchServiceBean searchService;
+
+    @EJB
+    PermissionServiceBean permissionService;
+
+    @EJB
+    DvObjectServiceBean dvObjectService;
+
+    @EJB
+    DataverseFacetServiceBean dataverseFacetService;
+
+    @EJB
+    FeaturedDataverseServiceBean featuredDataverseService;
+
+    @EJB
+    DataFileServiceBean dataFileService;
+
+    @EJB
+    TemplateServiceBean templateService;
+    
+    @EJB
+    SavedSearchServiceBean savedSearchService;
+
+    @EJB
+    DataverseFieldTypeInputLevelServiceBean fieldTypeInputLevels;
+
+    @EJB
+    DOIEZIdServiceBean doiEZId;
+    
+    @EJB
+    HandlenetServiceBean handleNet;
+    
+    @EJB
+    SettingsServiceBean settings;
+    
+    @EJB
+    GuestbookServiceBean guestbookService;
+    
+    @EJB
+    GuestbookResponseServiceBean responses;
+    
+    @EJB
+    DataverseLinkingServiceBean dvLinking;
+    
+    @EJB
+    DatasetLinkingServiceBean dsLinking;
+
+    @EJB
+    ExplicitGroupServiceBean explicitGroups;
+    
+    @EJB
+    RoleAssigneeServiceBean roleAssignees;
+    
+    @EJB
+    UserNotificationServiceBean userNotificationService;   
+    
+    @EJB
+    AuthenticationServiceBean authentication; 
+    
+    @PersistenceContext(unitName = "VDCNet-ejbPU")
+    private EntityManager em;
+    
+    @EJB
+    ActionLogServiceBean logSvc;
+
+    private CommandContext ctxt;
+    
+    @TransactionAttribute(REQUIRES_NEW)
+    public <R> R submitInNewTransaction(Command<R> aCommand) throws CommandException {
+        return submit(aCommand);
+    }
+
+    public <R> R submit(Command<R> aCommand) throws CommandException {
+        
+        final ActionLogRecord logRec = new ActionLogRecord(ActionLogRecord.ActionType.Command, aCommand.getClass().getCanonicalName());
+        
+        try {
+            logRec.setUserIdentifier( aCommand.getUser().getIdentifier() );
+            
+            // Check permissions - or throw an exception
+            Map<String, ? extends Set<Permission>> requiredMap = aCommand.getRequiredPermissions();
+            if (requiredMap == null) {
+                throw new RuntimeException("Command " + aCommand + " does not define required permissions.");
+            }
+
+            User user = aCommand.getUser();
+            
+            Map<String, DvObject> affectedDvObjects = aCommand.getAffectedDvObjects();
+            logRec.setInfo( describe(affectedDvObjects) );
+            for (Map.Entry<String, ? extends Set<Permission>> pair : requiredMap.entrySet()) {
+                String dvName = pair.getKey();
+                if (!affectedDvObjects.containsKey(dvName)) {
+                    throw new RuntimeException("Command instance " + aCommand + " does not have a DvObject named '" + dvName + "'");
+                }
+                DvObject dvo = affectedDvObjects.get(dvName);
+
+                Set<Permission> granted = (dvo != null) ? permissionService.permissionsFor(user, dvo)
+                        : EnumSet.allOf(Permission.class);
+                Set<Permission> required = requiredMap.get(dvName);
+                if (!granted.containsAll(required)) {
+                    required.removeAll(granted);
+                    logRec.setActionResult(ActionLogRecord.Result.PermissionError);
+                    throw new PermissionException("Can't execute command " + aCommand
+                            + ", because user " + aCommand.getUser()
+                            + " is missing permissions " + required
+                            + " on Object " + dvo.accept(DvObject.NamePrinter),
+                            aCommand,
+                            required, dvo);
+                }
+            }
+            try {
+                return aCommand.execute(getContext());
+                
+            } catch ( EJBException ejbe ) {
+                logRec.setActionResult(ActionLogRecord.Result.InternalError);                
+                throw new CommandException("Command " + aCommand.toString() + " failed: " + ejbe.getMessage(), ejbe.getCausedByException(), aCommand);
+            }
+            
+        } catch ( RuntimeException re ) {
+            logRec.setActionResult(ActionLogRecord.Result.InternalError);
+            logRec.setInfo( re.getMessage() );   
+            
+            Throwable cause = re;          
+            while (cause != null) {
+                if (cause instanceof ConstraintViolationException) {
+                    StringBuilder sb = new StringBuilder(); 
+                    sb.append("Unexpected bean validation constraint exception:"); 
+                    ConstraintViolationException constraintViolationException = (ConstraintViolationException) cause;
+                    for (ConstraintViolation<?> violation : constraintViolationException.getConstraintViolations()) {
+                        sb.append(" Invalid value: <<<").append(violation.getInvalidValue()).append(">>> for ").append(violation.getPropertyPath()).append(" at ").append(violation.getLeafBean()).append(" - ").append(violation.getMessage());
+                    }
+                    logger.log(Level.SEVERE, sb.toString());
+                    // set this more detailed info in action log
+                    logRec.setInfo( sb.toString() );
+                }
+                cause = cause.getCause();
+            }           
+            
+            throw re;
+            
+        } finally {
+            if ( logRec.getActionResult() == null ) {
+                logRec.setActionResult( ActionLogRecord.Result.OK );
+            }
+            logRec.setEndTime( new java.util.Date() );
+            logSvc.log(logRec);
+        }
+    }
+
+    public CommandContext getContext() {
+        if (ctxt == null) {
+            ctxt = new CommandContext() {
+                
+                @Override
+                public DatasetServiceBean datasets() {
+                    return datasetService;
+                }
+
+                @Override
+                public DataverseServiceBean dataverses() {
+                    return dataverseService;
+                }
+
+                @Override
+                public DataverseRoleServiceBean roles() {
+                    return rolesService;
+                }
+
+                @Override
+                public BuiltinUserServiceBean builtinUsers() {
+                    return usersService;
+                }
+
+                @Override
+                public IndexServiceBean index() {
+                    return indexService;
+                }
+
+                @Override
+                public SolrIndexServiceBean solrIndex() {
+                    return solrIndexService;
+                }
+
+                @Override
+                public SearchServiceBean search() {
+                    return searchService;
+                }
+
+                @Override
+                public PermissionServiceBean permissions() {
+                    return permissionService;
+                }
+
+                @Override
+                public DvObjectServiceBean dvObjects() {
+                    return dvObjectService;
+                }
+
+                @Override
+                public DataFileServiceBean files() {
+                    return dataFileService;
+                }
+
+                @Override
+                public EntityManager em() {
+                    return em;
+                }
+
+                @Override
+                public DataverseFacetServiceBean facets() {
+                    return dataverseFacetService;
+                }
+
+                @Override
+                public FeaturedDataverseServiceBean featuredDataverses() {
+                    return featuredDataverseService;
+                }
+
+                @Override
+                public TemplateServiceBean templates() {
+                    return templateService;
+                }
+                
+                @Override
+                public SavedSearchServiceBean savedSearches() {
+                    return savedSearchService;
+                }
+
+                @Override
+                public DataverseFieldTypeInputLevelServiceBean fieldTypeInputLevels() {
+                    return fieldTypeInputLevels;
+                }
+
+                @Override
+                public DOIEZIdServiceBean doiEZId() {
+                    return doiEZId;
+                }
+                
+                @Override
+                public HandlenetServiceBean handleNet() {
+                    return handleNet;
+                }
+
+                @Override
+                public SettingsServiceBean settings() {
+                    return settings;
+                }
+                
+                @Override
+                public GuestbookServiceBean guestbooks() {
+                    return guestbookService;
+                }
+
+                @Override
+                public GuestbookResponseServiceBean responses() {
+                    return responses;
+                }
+                
+                @Override
+                public DataverseLinkingServiceBean dvLinking() {
+                    return dvLinking;
+                }
+                                
+                @Override
+                public DatasetLinkingServiceBean dsLinking() {
+                    return dsLinking;
+                }
+                @Override
+                public DataverseEngine engine() {
+                    return new DataverseEngine() {
+                        @Override
+                        public <R> R submit(Command<R> aCommand) throws CommandException {
+                            return EjbDataverseEngine.this.submit(aCommand);
+                        }
+                    };
+                }
+
+                @Override
+                public ExplicitGroupServiceBean explicitGroups() {
+                    return explicitGroups;
+                }
+
+                @Override
+                public RoleAssigneeServiceBean roleAssignees() {
+                    return roleAssignees;
+                }
+                
+                @Override
+                public UserNotificationServiceBean notifications() {
+                    return userNotificationService;
+                } 
+                
+                @Override
+                public AuthenticationServiceBean authentication() {
+                    return authentication;
+                } 
+                
+            };
+        }
+
+        return ctxt;
+    }
+    
+    
+    private String describe( Map<String, DvObject> dvObjMap ) {
+        StringBuilder sb = new StringBuilder();
+        for ( Map.Entry<String, DvObject> ent : dvObjMap.entrySet() ) {
+            DvObject value = ent.getValue();
+            sb.append(ent.getKey()).append(":");
+            sb.append( (value!=null) ? value.accept(DvObject.NameIdPrinter) : "<null>");
+            sb.append(" ");
+        }
+        return sb.toString();
+    }
+}