2828// MongoDB imports
2929import org .bson .Document ;
3030import org .bson .types .Binary ;
31+ import org .bson .types .ObjectId ;
3132import org .bson .conversions .Bson ;
3233import com .mongodb .client .*;
3334import com .mongodb .client .gridfs .*;
@@ -110,7 +111,7 @@ public void systemSetup() {
110111 // We insert a "root" object, to ensure the tables are initialized
111112 // ---
112113 if (!fullRawPathExist ("root" )) {
113- setupAnchorFile ("root" , "root" , "root" );
114+ setupAnchorFile_withFullRawPath ("root" , "root" , "root" );
114115 }
115116
116117 // Lets setup the index for the metadata fields (which is not enabled by default)
@@ -172,7 +173,7 @@ public boolean backend_workspaceExist(String oid) {
172173 public void backend_setupWorkspace (String oid ) {
173174 // We setup a blank file with type root
174175 if (!fullRawPathExist (oid )) {
175- setupAnchorFile (oid , oid , "space" );
176+ setupAnchorFile_withFullRawPath (oid , oid , "space" );
176177 }
177178 }
178179
@@ -219,10 +220,16 @@ protected boolean prefixPathExist(String oid, String path) {
219220 // Lets build the query for the "root file"
220221 Bson query = null ;
221222
223+ // Get the full prefixpath
224+ String fullPrefixPath = oid +"/" +path ;
225+
222226 // Remove matching path
223- query = Filters .and (
224- Filters .eq ("metadata.oid" , oid ),
225- Filters .regex ("filename" , "^" +Pattern .quote (oid +"/" +path )+".*" )
227+ query = Filters .or (
228+ Filters .eq ("filename" , fullPrefixPath ),
229+ Filters .and (
230+ Filters .eq ("metadata.oid" , oid ),
231+ Filters .regex ("filename" , "^" +Pattern .quote (fullPrefixPath )+".*" )
232+ )
226233 );
227234
228235 // Lets prepare the search
@@ -241,8 +248,9 @@ protected boolean prefixPathExist(String oid, String path) {
241248
242249 /**
243250 * Setup an empty file, used for various use cases
251+ * The extended funciton name is intentional to avoid confusion of "full path" with "path"
244252 */
245- public void setupAnchorFile (String oid , String fullPath , String type ) {
253+ public void setupAnchorFile_withFullRawPath (String oid , String fullPath , String type ) {
246254 // In general we will upload a blank file
247255 // with the relevent oid, that can be easily lookedup
248256 //
@@ -255,7 +263,10 @@ public void setupAnchorFile(String oid, String fullPath, String type) {
255263
256264 // Prepare the upload options
257265 GridFSUploadOptions opt = (new GridFSUploadOptions ()).metadata (metadata );
258- gridFSBucket .uploadFromStream (fullPath , emptyStream , opt );
266+ ObjectId objID = gridFSBucket .uploadFromStream (fullPath , emptyStream , opt );
267+
268+ // Flush it?
269+ objID .toString ();
259270 } catch (IOException e ) {
260271 throw new RuntimeException (e );
261272 }
@@ -310,7 +321,6 @@ protected boolean removeFilePath(String oid, String path) {
310321 while (cursor .hasNext ()) {
311322 GridFSFile fileObj = cursor .next ();
312323 gridFSBucket .delete (fileObj .getId ());
313-
314324 rmFlag = true ;
315325 }
316326 }
@@ -319,8 +329,39 @@ protected boolean removeFilePath(String oid, String path) {
319329 return rmFlag ;
320330 }
321331
322- protected void performFileCleanup (String oid , String path ) {
332+ /**
333+ * Given the current path, enforce the parent pathing dir
334+ * Used mainly to ensure "parent" folder exists on file write/rm
335+ **/
336+ protected void ensureParentPath (String oid , String path ) {
337+ // Does nothing if path is empty
338+ if ( path == null || path .equals ("/" ) || path .isEmpty () ) {
339+ return ;
340+ }
341+
342+ // Cleanup ending slash
343+ if ( path .endsWith ("/" ) ) {
344+ path = path .substring (0 , path .length () - 1 );
345+ }
346+
347+ // Get the parent path
348+ String parPath = normalizeFolderPathString ( FileUtil .getParentPath (path ) );
349+
350+ // Does nothing if folder path is "blank"
351+ if ( parPath == null || parPath .equals ("/" ) || parPath .isEmpty () ) {
352+ return ;
353+ }
354+
355+ // Path enforcement
356+ backend_ensureFolderPath (oid , parPath );
357+ }
323358
359+ /**
360+ * Because mongoDB does file versioining on each save, we would need to cleanup
361+ * older file versions where applicable, in a safe way
362+ */
363+ protected void performVersionedFileCleanup (String oid , String path ) {
364+ // @TODO !!!
324365 }
325366
326367 //--------------------------------------------------------------------------
@@ -383,7 +424,8 @@ public void backend_fileWriteInputStream(final String oid, final String filepath
383424
384425 // Prepare the upload options
385426 GridFSUploadOptions opt = (new GridFSUploadOptions ()).metadata (metadata );
386- gridFSBucket .uploadFromStream (fullPath , data , opt );
427+ ObjectId objID = gridFSBucket .uploadFromStream (fullPath , data , opt );
428+ objID .toString ();
387429 } catch (Exception e ) {
388430 throw new RuntimeException (e );
389431 } finally {
@@ -455,6 +497,7 @@ public boolean backend_fileExist(String oid, String filepath) {
455497
456498 @ Override
457499 public void backend_removeFile (String oid , String filepath ) {
500+ ensureParentPath (oid , filepath );
458501 removeFilePath (oid , filepath );
459502 }
460503
@@ -473,6 +516,7 @@ public void backend_removeFile(String oid, String filepath) {
473516 * @return the stored byte array of the file
474517 **/
475518 public void backend_removeFolderPath (final String oid , final String folderPath ) {
519+ ensureParentPath (oid , folderPath );
476520 removeFilePathRecursively (oid , folderPath );
477521 }
478522
@@ -504,8 +548,8 @@ public boolean backend_folderPathExist(final String oid, final String folderPath
504548 public void backend_ensureFolderPath (final String oid , final String folderPath ) {
505549 // We setup a blank file with type root, this checks only for the anchor file
506550 // if it does not exists, we will make it
507- if (! fullRawPathExist (oid +"/" +folderPath )) {
508- setupAnchorFile (oid , folderPath , "dir" );
551+ if (fullRawPathExist (oid +"/" +folderPath ) == false ) {
552+ setupAnchorFile_withFullRawPath (oid , oid + "/" + folderPath , "dir" );
509553 }
510554 }
511555
@@ -599,15 +643,13 @@ public Set<String> backend_getFileAndFolderPathSet(final String oid, String fold
599643 // Query using oid and the path
600644 fullPrefixPath = fullPrefixPath +folderPath ;
601645
602- // Remove matching path
646+ // Filter for matching path
603647 query = Filters .and (
604648 Filters .eq ("metadata.oid" , oid ),
605649 Filters .regex ("filename" , "^" +Pattern .quote (fullPrefixPath )+".*" )
606650 );
607651 }
608652
609- query = Filters .eq ("metadata.oid" , oid );
610-
611653 // The return set
612654 Set <String > ret = new HashSet <>();
613655
0 commit comments