Wiki source code of Filesystem store
Version 2.1 by Thomas Mortagne on 2024/05/22
Hide last authors
author | version | line-number | content |
---|---|---|---|
![]() |
1.68 | 1 | {{box cssClass="floatinginfobox" title="**Contents**"}}{{toc start="2"/}}{{/box}} |
2 | |||
![]() |
1.69 | 3 | By default in XWiki the content of attachments and deleted attachment and documents are stored in what we call the "filesystem store". By default it's located in ##<permanentdir>/store/file##. |
![]() |
1.1 | 4 | |
![]() |
1.55 | 5 | It's a simple file based storage in which documents and attachments references are (md5) hashed, to avoid problems with various limited (in terms of encoding and path size) file systems. |
![]() |
1.1 | 6 | |
![]() |
1.70 | 7 | For example the attachment ##XWikiLogo.png## in document ##Sandbox.WebHome## is stored in the following location: ##/1/0/5d42329a923e687f5dff4887d80098/attachments/9/2/0bc685fa0da28168319c0126def81b##. |
![]() |
1.1 | 8 | |
![]() |
1.26 | 9 | {{box title="And where is my entity located ?"}} |
![]() |
1.25 | 10 | {{velocity}} |
![]() |
1.19 | 11 | {{html}} |
12 | <form> | ||
![]() |
1.30 | 13 | <input type="text" name="reference"#if($request.reference) value="$escapetool.xml($request.reference)#end"/> |
![]() |
1.20 | 14 | <button name="serialize_document">Document</button> |
15 | <button name="serialize_attachment">Attachment</button> | ||
![]() |
1.19 | 16 | </form> |
17 | {{/html}} | ||
![]() |
1.25 | 18 | {{/velocity}} |
![]() |
1.19 | 19 | |
![]() |
1.42 | 20 | {{groovy}} |
![]() |
1.16 | 21 | def hash(str) |
22 | { | ||
![]() |
1.49 | 23 | md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(str) |
![]() |
1.71 | 24 | println "1. It's then md5 hashed (##${md5}##)." |
![]() |
1.32 | 25 | |
![]() |
1.49 | 26 | char0 = md5.charAt(0) |
![]() |
1.71 | 27 | println "1. A first folder is created with the first character of the hash (##${char0}##)." |
![]() |
1.32 | 28 | |
![]() |
1.49 | 29 | char1 = md5.charAt(1) |
![]() |
1.71 | 30 | println "1. A second folder is created with the second character of the hash (##${char1}##)." |
![]() |
1.32 | 31 | |
![]() |
1.49 | 32 | charn = md5.substring(2) |
![]() |
1.71 | 33 | println "1. A third folder is created with the remaining characters (##${charn}##)." |
![]() |
1.9 | 34 | |
![]() |
1.52 | 35 | return "**$char0**/**$char1**/**$charn**" |
![]() |
1.16 | 36 | } |
37 | |||
![]() |
1.17 | 38 | def encodeDocument(documentReference) { |
![]() |
1.24 | 39 | path = "" |
![]() |
1.29 | 40 | if (documentReference.root.type == org.xwiki.model.EntityType.WIKI) { |
![]() |
1.71 | 41 | println "1. A folder with the wiki name (##${documentReference.root.name}##) is created." |
![]() |
1.29 | 42 | path = documentReference.root.name |
![]() |
1.24 | 43 | } |
44 | |||
![]() |
1.49 | 45 | localuid = services.component.getInstance(org.xwiki.model.reference.EntityReferenceSerializer.TYPE_STRING, "local/uid").serialize(documentReference) |
![]() |
1.71 | 46 | println "1. The document reference is serialized using the local uid serializer (##${localuid}##)." |
![]() |
1.32 | 47 | |
![]() |
1.24 | 48 | path += "/" + hash(localuid) |
49 | |||
50 | return path; | ||
![]() |
1.16 | 51 | } |
52 | |||
![]() |
1.17 | 53 | def encodeAttachment(attachmentReference) { |
![]() |
1.16 | 54 | path = "" |
55 | if (reference.parent) { | ||
56 | path = encodeDocument(attachmentReference.parent) | ||
57 | } | ||
58 | |||
![]() |
1.49 | 59 | path += "/attachments" |
![]() |
1.71 | 60 | println "1. An ##attachments## folder is created." |
![]() |
1.16 | 61 | |
![]() |
1.49 | 62 | name = attachmentReference.name |
![]() |
1.71 | 63 | println "1. The attachment name (##$name##) is extracted from the reference." |
![]() |
1.49 | 64 | |
![]() |
1.51 | 65 | path += "/" + hash(name) + "" |
![]() |
1.16 | 66 | } |
67 | |||
![]() |
1.22 | 68 | if (request.serialize_document != null) { |
![]() |
1.28 | 69 | reference = services.component.getInstance(org.xwiki.model.reference.EntityReferenceResolver.TYPE_STRING, "relative").resolve(request.reference, org.xwiki.model.EntityType.DOCUMENT) |
![]() |
1.16 | 70 | |
![]() |
1.70 | 71 | println "{{info}}" |
72 | path = encodeDocument(reference) | ||
73 | println "{{/info}}" | ||
74 | |||
75 | println "" | ||
76 | print "The final path of the folder which contains the content of this attachment is ##$path##." | ||
![]() |
1.22 | 77 | } else if (request.serialize_attachment != null) { |
![]() |
1.23 | 78 | reference = services.component.getInstance(org.xwiki.model.reference.EntityReferenceResolver.TYPE_STRING, "relative").resolve(request.reference, org.xwiki.model.EntityType.ATTACHMENT) |
![]() |
1.16 | 79 | |
![]() |
1.41 | 80 | println "{{info}}" |
![]() |
1.36 | 81 | path = encodeAttachment(reference) |
![]() |
1.41 | 82 | println "{{/info}}" |
![]() |
1.36 | 83 | |
![]() |
1.33 | 84 | println "" |
![]() |
1.70 | 85 | print "The final path of the folder which contains the content of this document is ##$path##." |
![]() |
1.2 | 86 | } |
87 | {{/groovy}} | ||
![]() |
1.18 | 88 | {{/box}} |
![]() |
1.55 | 89 | |
![]() |
1.72 | 90 | == Attachments and deleted attachments |
![]() |
1.60 | 91 | |
![]() |
1.65 | 92 | By default, inside the attachment folder, you will find both the current version of the attachment and its history. The file name is always ##f##, it's then optionally followed by the version (when it's a piece of the history) and the original file extension. |
![]() |
1.55 | 93 | |
![]() |
1.59 | 94 | * ##f.png## |
![]() |
1.64 | 95 | * ##fv1.1.png## |
96 | * ##fv2.1.png## | ||
![]() |
1.59 | 97 | |
![]() |
1.55 | 98 | {{version since="16.4.0"}} |
![]() |
1.58 | 99 | Most of the time, instead of the current version of the attachment, a "link" is created. It's a file named ##f.lnk## which contains the relative path it's representing. In standard condition, it always points to the latest version of the attachment. |
![]() |
1.55 | 100 | {{/version}} |
![]() |
1.59 | 101 | |
![]() |
2.1 | 102 | * ##f.png.lnk## {{info}}contains the string ##fv2.1.png##{{/info}} |
![]() |
1.63 | 103 | * ##fv1.1.png## |
104 | * ##fv2.1.png## | ||
![]() |
1.67 | 105 | |
![]() |
2.1 | 106 | == Deleted attachments |
![]() |
1.67 | 107 | |
108 | |||
![]() |
2.1 | 109 | |
![]() |
1.67 | 110 | == Deleted documents |
111 | |||
112 |