View Javadoc
1   package de.dlr.shepard.neo4Core.services;
2   
3   import de.dlr.shepard.exceptions.InvalidAuthException;
4   import de.dlr.shepard.exceptions.InvalidBodyException;
5   import de.dlr.shepard.exceptions.InvalidRequestException;
6   import de.dlr.shepard.mongoDB.FileService;
7   import de.dlr.shepard.mongoDB.NamedInputStream;
8   import de.dlr.shepard.mongoDB.ShepardFile;
9   import de.dlr.shepard.neo4Core.dao.DataObjectDAO;
10  import de.dlr.shepard.neo4Core.dao.FileContainerDAO;
11  import de.dlr.shepard.neo4Core.dao.FileReferenceDAO;
12  import de.dlr.shepard.neo4Core.dao.ShepardFileDAO;
13  import de.dlr.shepard.neo4Core.dao.UserDAO;
14  import de.dlr.shepard.neo4Core.dao.VersionDAO;
15  import de.dlr.shepard.neo4Core.entities.FileReference;
16  import de.dlr.shepard.neo4Core.entities.Version;
17  import de.dlr.shepard.neo4Core.io.FileReferenceIO;
18  import de.dlr.shepard.security.PermissionsUtil;
19  import de.dlr.shepard.util.AccessType;
20  import de.dlr.shepard.util.DateHelper;
21  import io.quarkus.logging.Log;
22  import jakarta.enterprise.context.RequestScoped;
23  import jakarta.inject.Inject;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  @RequestScoped
28  public class FileReferenceService implements IReferenceService<FileReference, FileReferenceIO> {
29  
30    private FileReferenceDAO fileReferenceDAO;
31    private DataObjectDAO dataObjectDAO;
32    private FileContainerDAO containerDAO;
33    private ShepardFileDAO fileDAO;
34    private UserDAO userDAO;
35    private VersionDAO versionDAO;
36    private DateHelper dateHelper;
37    private FileService fileService;
38    private PermissionsUtil permissionsUtil;
39  
40    FileReferenceService() {}
41  
42    @Inject
43    public FileReferenceService(
44      FileReferenceDAO fileReferenceDAO,
45      DataObjectDAO dataObjectDAO,
46      FileContainerDAO containerDAO,
47      ShepardFileDAO fileDAO,
48      UserDAO userDAO,
49      VersionDAO versionDAO,
50      DateHelper dateHelper,
51      FileService fileService,
52      PermissionsUtil permissionsUtil
53    ) {
54      this.fileReferenceDAO = fileReferenceDAO;
55      this.dataObjectDAO = dataObjectDAO;
56      this.containerDAO = containerDAO;
57      this.fileDAO = fileDAO;
58      this.userDAO = userDAO;
59      this.versionDAO = versionDAO;
60      this.dateHelper = dateHelper;
61      this.fileService = fileService;
62      this.permissionsUtil = permissionsUtil;
63    }
64  
65    @Override
66    public List<FileReference> getAllReferencesByDataObjectShepardId(long dataObjectShepardId) {
67      var references = fileReferenceDAO.findByDataObjectShepardId(dataObjectShepardId);
68      return references;
69    }
70  
71    @Override
72    public FileReference getReferenceByShepardId(long shepardId) {
73      FileReference fileReference = fileReferenceDAO.findByShepardId(shepardId);
74      if (fileReference == null || fileReference.isDeleted()) {
75        Log.errorf("File Reference with id %s is null or deleted", shepardId);
76        return null;
77      }
78      return fileReference;
79    }
80  
81    @Override
82    public FileReference createReferenceByShepardId(
83      long dataObjectShepardId,
84      FileReferenceIO fileReference,
85      String username
86    ) {
87      var user = userDAO.find(username);
88      var dataObject = dataObjectDAO.findLightByShepardId(dataObjectShepardId);
89      var container = containerDAO.findLightByNeo4jId(fileReference.getFileContainerId());
90      if (container == null || container.isDeleted()) throw new InvalidBodyException("invalid container");
91      var toCreate = new FileReference();
92      toCreate.setCreatedAt(dateHelper.getDate());
93      toCreate.setCreatedBy(user);
94      toCreate.setDataObject(dataObject);
95      toCreate.setName(fileReference.getName());
96      toCreate.setFileContainer(container);
97  
98      // Get existing file
99      for (var oid : fileReference.getFileOids()) {
100       var file = fileDAO.find(container.getId(), oid);
101       if (file != null) {
102         toCreate.addFile(file);
103       } else {
104         Log.warnf("Could not find file with oid: %s", oid);
105       }
106     }
107 
108     var created = fileReferenceDAO.createOrUpdate(toCreate);
109     created.setShepardId(created.getId());
110     created = fileReferenceDAO.createOrUpdate(created);
111     Version version = versionDAO.findVersionLightByNeo4jId(dataObject.getId());
112     versionDAO.createLink(created.getId(), version.getUid());
113     return created;
114   }
115 
116   @Override
117   public boolean deleteReferenceByShepardId(long fileReferenceShepardId, String username) {
118     FileReference fileReference = fileReferenceDAO.findByShepardId(fileReferenceShepardId);
119     var user = userDAO.find(username);
120     fileReference.setDeleted(true);
121     fileReference.setUpdatedBy(user);
122     fileReference.setUpdatedAt(dateHelper.getDate());
123     fileReferenceDAO.createOrUpdate(fileReference);
124     return true;
125   }
126 
127   /**
128    * Returns list of ShepardFile. This works even when the container in question is not accessible.
129    *
130    * @param fileReferenceShepardId identifies the file reference
131    * @return list of shepard files
132    */
133   public List<ShepardFile> getFilesByShepardId(long fileReferenceShepardId) {
134     FileReference reference = fileReferenceDAO.findByShepardId(fileReferenceShepardId);
135     return reference.getFiles();
136   }
137 
138   /**
139    * Returns a NamedInputStream of the specified file
140    *
141    * @param fileReferenceShepardId identifies the file reference
142    * @param oid identifies the actual file
143    * @param username the current user
144    * @return NamedInputStream
145    * @throws InvalidRequestException when container is not accessible
146    * @throws InvalidAuthException when the user is not authorized to access the container
147    */
148   public NamedInputStream getPayloadByShepardId(long fileReferenceShepardId, String oid, String username) {
149     FileReference reference = fileReferenceDAO.findByShepardId(fileReferenceShepardId);
150     if (
151       reference.getFileContainer() == null || reference.getFileContainer().isDeleted()
152     ) throw new InvalidRequestException("The file container in question is not accessible");
153 
154     long containerId = reference.getFileContainer().getId();
155     if (
156       !permissionsUtil.isAccessTypeAllowedForUser(containerId, AccessType.Read, username)
157     ) throw new InvalidAuthException("You are not authorized to access this file");
158 
159     String mongoId = reference.getFileContainer().getMongoId();
160     return fileService.getPayload(mongoId, oid);
161   }
162 
163   /**
164    * Returns a list of NamedInputStreams of all files in that reference
165    *
166    * @param fileReferenceShepardId identifies the file reference
167    * @param username the current user
168    * @return list of NamedInputStreams
169    * @throws InvalidRequestException when container is not accessible
170    * @throws InvalidAuthException when the user is not authorized to access the container
171    */
172   public List<NamedInputStream> getAllPayloadsByShepardId(long fileReferenceShepardId, String username) {
173     FileReference reference = fileReferenceDAO.findByShepardId(fileReferenceShepardId);
174     var files = reference.getFiles();
175 
176     // Return empty named input streams when the container is not accessible
177     if (
178       reference.getFileContainer() == null || reference.getFileContainer().isDeleted()
179     ) throw new InvalidRequestException("The file container in question is not accessible");
180 
181     // Throw exception when not isAllowed
182     var containerId = reference.getFileContainer().getId();
183     if (
184       !permissionsUtil.isAccessTypeAllowedForUser(containerId, AccessType.Read, username)
185     ) throw new InvalidAuthException("You are not authorized to access this file container");
186 
187     var result = new ArrayList<NamedInputStream>(files.size());
188     for (var file : files) {
189       var nis = fileService.getPayload(reference.getFileContainer().getMongoId(), file.getOid());
190       if (nis != null) result.add(nis);
191       else result.add(new NamedInputStream(file.getOid(), null, file.getFilename(), 0L));
192     }
193     return result;
194   }
195 }