type, String key) {
}
}
- private static ConfigurationSource getConfigSource() throws ComponentLookupException {
- return getComponentManager().lookup(ConfigurationSource.class, "allproperties");
+ private static ConfigurationSource getConfigSource() {
+ return Utils.getComponent(ConfigurationSource.class, "allproperties");
}
private static ComponentManager getComponentManager() {
diff --git a/celements-xwiki-core/src/main/java/com/celements/store/att/AttachmentContentPolicy.java b/celements-xwiki-core/src/main/java/com/celements/store/att/AttachmentContentPolicy.java
new file mode 100644
index 000000000..feb22e5e0
--- /dev/null
+++ b/celements-xwiki-core/src/main/java/com/celements/store/att/AttachmentContentPolicy.java
@@ -0,0 +1,57 @@
+package com.celements.store.att;
+
+import javax.inject.Inject;
+
+import org.springframework.stereotype.Component;
+
+import com.celements.init.XWikiProvider;
+import com.xpn.xwiki.store.hibernate.HibernateAttachmentContentStore;
+
+/**
+ * Policy component that decides whether attachment binary content should be embedded into
+ * XML-based structures produced by XWiki, namely the attachment archive (RCS/XML history) and the
+ * attachment recycle bin entry (deleted attachment XML snapshot).
+ *
+ * The decision is based on the currently active {@code AttachmentContentStore} implementation.
+ * When the legacy Hibernate content store is used, attachment content is expected to be present in
+ * the serialized XML (RCS archive and recycle bin) because the Hibernate-based implementations
+ * historically persisted/consumed the bytes from there.
+ *
+ * When an alternative content storage is used (for example object storage), embedding raw bytes
+ * into these XML payloads is typically undesirable (size, duplication) and may be incompatible with
+ * the alternative store's lookup strategy. In that case, content should be excluded and retrieved
+ * via the configured {@code AttachmentContentStore} instead.
+ */
+@Component
+public class AttachmentContentPolicy {
+
+ private final XWikiProvider xwikiProvider;
+
+ @Inject
+ public AttachmentContentPolicy(XWikiProvider xwikiProvider) {
+ this.xwikiProvider = xwikiProvider;
+ }
+
+ /**
+ * Determines whether attachment content should be embedded into the attachment archive XML.
+ */
+ public boolean includeInArchive() {
+ return isHibernateAttachmentContentStore();
+ }
+
+ /**
+ * Determines whether attachment content should be embedded into recycle bin XML.
+ */
+ public boolean includeInRecycleBin() {
+ return isHibernateAttachmentContentStore();
+ }
+
+ private boolean isHibernateAttachmentContentStore() {
+ return xwikiProvider.get().orElseThrow(IllegalStateException::new)
+ .getAttachmentStore()
+ .getContentStore()
+ .getStoreName()
+ .equals(HibernateAttachmentContentStore.STORE_NAME);
+ }
+
+}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/XWiki.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/XWiki.java
index 058ed4a34..455d875f9 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/XWiki.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/XWiki.java
@@ -50,6 +50,7 @@
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TimeZone;
@@ -184,9 +185,6 @@ public class XWiki implements EventListener {
/** The attachment storage (excluding attachment history). */
private XWikiAttachmentStoreInterface attachmentStore;
- /** Store for attachment archives. */
- private AttachmentVersioningStore attachmentVersioningStore;
-
/** Document versioning storage. */
private XWikiVersioningStoreInterface versioningStore;
@@ -377,18 +375,14 @@ protected void initXWiki() throws XWikiException {
"com.xpn.xwiki.criteria.impl.XWikiCriteriaServiceImpl", context));
LOGGER.trace("initialising AttachmentStore...");
- setAttachmentStore(Utils.getComponent(XWikiAttachmentStoreInterface.class, Param(
- "xwiki.store.attachment.hint")));
+ setAttachmentStore(StoreFactory.getAttachmentStore());
+ getAttachmentStore().getContentStore(); // force init
+ getAttachmentStore().getVersioningStore(); // force init
LOGGER.trace("initialising VersioningStore...");
setVersioningStore(Utils.getComponent(XWikiVersioningStoreInterface.class, Param(
"xwiki.store.versioning.hint")));
- LOGGER.trace("initialising AttachmentVersioningStore...");
- setAttachmentVersioningStore(Utils.getComponent(AttachmentVersioningStore.class,
- hasAttachmentVersioning(context) ? Param("xwiki.store.attachment.versioning.hint")
- : "void"));
-
LOGGER.trace("initialising RecycleBinStore...");
StoreFactory.getRecycleBinStore().ifPresent(this::setRecycleBinStore);
@@ -414,6 +408,23 @@ protected void initXWiki() throws XWikiException {
LOGGER.debug("XWiki init done");
}
+ public String printConfig() {
+ return "XWiki "
+ + "[ mainStore=" + getStore().getClass().getName()
+ + ", notCacheStore=" + getNotCacheStore().getClass().getName()
+ + ", versioningStore=" + getVersioningStore().getClass().getName()
+ + ", recycleBinStore=" + Optional.ofNullable(getRecycleBinStore())
+ .map(s -> s.getClass().getName()).orElse("none")
+ + ", attachmentStore=" + getAttachmentStore().getClass().getName()
+ + ", attachmentContentStore=" + getAttachmentStore().getContentStore().getClass().getName()
+ + ", attachmentVersioningStore=" + getAttachmentStore().getVersioningStore()
+ .getClass().getName()
+ + ", attachmentRecycleBinStore=" + Optional.ofNullable(getAttachmentRecycleBinStore())
+ .map(s -> s.getClass().getName()).orElse("none")
+ + ", renderingEngine=" + getRenderingEngine().getClass().getName()
+ + "]";
+ }
+
/**
* Ensure that mandatory classes (ie classes XWiki needs to work properly) exist and create them
* if they don't exist.
@@ -782,7 +793,7 @@ public XWikiAttachmentStoreInterface getAttachmentStore() {
}
public AttachmentVersioningStore getAttachmentVersioningStore() {
- return this.attachmentVersioningStore;
+ return getAttachmentStore().getVersioningStore();
}
public XWikiVersioningStoreInterface getVersioningStore() {
@@ -2216,10 +2227,6 @@ public void setAttachmentStore(XWikiAttachmentStoreInterface attachmentStore) {
this.attachmentStore = attachmentStore;
}
- public void setAttachmentVersioningStore(AttachmentVersioningStore avStore) {
- this.attachmentVersioningStore = avStore;
- }
-
public void setVersioningStore(XWikiVersioningStoreInterface versioningStore) {
this.versioningStore = versioningStore;
}
@@ -5150,7 +5157,7 @@ public boolean hasVersioning(String fullName, XWikiContext context) {
@Deprecated
public boolean hasAttachmentVersioning(XWikiContext context) {
- return ("1".equals(Param("xwiki.store.attachment.versioning", "1")));
+ return getAttachmentStore().getVersioningStore().hasVersioning();
}
public String getExternalAttachmentURL(String fullName, String filename, XWikiContext context) {
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/Attachment.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/Attachment.java
index 262e92dec..0d698df60 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/Attachment.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/Attachment.java
@@ -141,7 +141,7 @@ public String getContentAsString(String charset) throws XWikiException {
}
public Version[] getVersions() throws XWikiException {
- attachment.loadArchive(getXWikiContext());
+ attachment.loadArchive();
return attachment.getVersions();
}
@@ -150,7 +150,7 @@ public Version[] getVersions() throws XWikiException {
* @throws XWikiException
*/
public List getVersionList() throws XWikiException {
- attachment.loadArchive(getXWikiContext());
+ attachment.loadArchive();
return attachment.getVersionList();
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedAttachment.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedAttachment.java
index 02c005d30..d707e6df2 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedAttachment.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedAttachment.java
@@ -22,8 +22,8 @@
import java.util.Calendar;
import java.util.Date;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.xpn.xwiki.XWikiConfig;
import com.xpn.xwiki.XWikiContext;
@@ -47,7 +47,7 @@
public class DeletedAttachment extends Api {
/** Logging helper object. */
- private static final Log LOG = LogFactory.getLog(DeletedAttachment.class);
+ private static final Logger LOG = LoggerFactory.getLogger(DeletedAttachment.class);
/** The internal object wrapped by this API. */
private final com.xpn.xwiki.doc.DeletedAttachment deletedAttachment;
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedDocument.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedDocument.java
index 2476d82d6..4cb8500fd 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedDocument.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/api/DeletedDocument.java
@@ -22,8 +22,8 @@
import java.util.Calendar;
import java.util.Date;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.xpn.xwiki.XWikiConfig;
import com.xpn.xwiki.XWikiContext;
@@ -40,7 +40,7 @@
public class DeletedDocument extends Api {
/** Logging helper object. */
- private static final Log LOG = LogFactory.getLog(DeletedDocument.class);
+ private static final Logger LOG = LoggerFactory.getLogger(DeletedDocument.class);
/**
* The internal object wrapped by this API.
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/DeletedAttachment.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/DeletedAttachment.java
index 5bcd77a98..0f9da79c4 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/DeletedAttachment.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/DeletedAttachment.java
@@ -73,20 +73,20 @@ protected DeletedAttachment() {}
* User which deleted the attachment.
* @param deleteDate
* Date of delete action.
- * @param context
- * The current context. Used for determining the encoding.
+ * @param bWithAttachmentContent
+ * True to include the attachment content in the recycle bin
* @throws XWikiException
* If the attachment cannot be exported to XML.
*/
public DeletedAttachment(XWikiAttachment attachment, String deleter, Date deleteDate,
- XWikiContext context)
+ boolean bWithAttachmentContent)
throws XWikiException {
this.docId = attachment.getDocId();
this.docName = attachment.getDoc().getFullName();
this.filename = attachment.getFilename();
this.deleter = deleter;
this.date = deleteDate;
- setAttachment(attachment, context);
+ setAttachment(attachment, bWithAttachmentContent);
}
/**
@@ -233,9 +233,9 @@ protected void setXml(String xml) {
* @throws XWikiException
* if an exception occurs during the XML export
*/
- protected void setAttachment(XWikiAttachment attachment, XWikiContext context)
+ protected void setAttachment(XWikiAttachment attachment, boolean bWithAttachmentContent)
throws XWikiException {
- setXml(attachment.toStringXML(true, true, context));
+ setXml(attachment.toStringXML(bWithAttachmentContent, true));
}
/**
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java
index 4e1ea79ed..566bbb62b 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java
@@ -21,6 +21,10 @@
package com.xpn.xwiki.doc;
+import static com.celements.execution.XWikiExecutionProp.*;
+import static com.celements.spring.context.SpringContextProvider.*;
+
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -28,11 +32,10 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
@@ -40,17 +43,26 @@
import org.dom4j.dom.DOMElement;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.rcs.Archive;
import org.suigeneris.jrcs.rcs.Version;
+import org.xwiki.context.Execution;
+import org.xwiki.model.reference.AttachmentReference;
+import org.xwiki.model.reference.DocumentReference;
+import org.xwiki.model.reference.WikiReference;
+import com.celements.init.XWikiProvider;
+import com.google.common.base.Strings;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.internal.xml.DOMXMLWriter;
import com.xpn.xwiki.internal.xml.XMLWriter;
+import com.xpn.xwiki.store.XWikiAttachmentStoreInterface;
public class XWikiAttachment implements Cloneable {
- private static final Log LOG = LogFactory.getLog(XWikiAttachment.class);
+ private static final Logger LOG = LoggerFactory.getLogger(XWikiAttachment.class);
private XWikiDocument doc;
@@ -169,7 +181,6 @@ public int getContentSize(XWikiContext context) throws XWikiException {
if (this.attachment_content == null) {
this.doc.loadAttachmentContent(this, context);
}
-
return this.attachment_content.getSize();
}
@@ -245,6 +256,25 @@ public void setDoc(XWikiDocument doc) {
this.doc = doc;
}
+ public AttachmentReference getAttachmentReference() {
+ if ((doc != null) && !Strings.isNullOrEmpty(filename)) {
+ return new AttachmentReference(filename, doc.getDocumentReference());
+ }
+ return null;
+ }
+
+ public DocumentReference getDocumentReference() {
+ return Optional.ofNullable(getAttachmentReference())
+ .map(AttachmentReference::getDocumentReference)
+ .orElse(null);
+ }
+
+ public WikiReference getWikiReference() {
+ return Optional.ofNullable(getDocumentReference())
+ .map(DocumentReference::getWikiReference)
+ .orElse(null);
+ }
+
public Date getDate() {
return this.date;
}
@@ -282,6 +312,12 @@ public void setMetaDataDirty(boolean metaDataDirty) {
this.isMetaDataDirty = metaDataDirty;
}
+ @Deprecated
+ public String toStringXML(boolean bWithAttachmentContent, boolean bWithVersions,
+ XWikiContext context) throws XWikiException {
+ return toStringXML(bWithAttachmentContent, bWithVersions);
+ }
+
/**
* Retrieve an attachment as an XML string. You should prefer
* {@link #toXML(com.xpn.xwiki.internal.xml.XMLWriter, boolean, boolean, com.xpn.xwiki.XWikiContext)
@@ -297,8 +333,7 @@ public void setMetaDataDirty(boolean metaDataDirty) {
* @throws XWikiException
* when an error occurs during wiki operations
*/
- public String toStringXML(boolean bWithAttachmentContent, boolean bWithVersions,
- XWikiContext context)
+ public String toStringXML(boolean bWithAttachmentContent, boolean bWithVersions)
throws XWikiException {
// This is very bad. baos holds the entire attachment on the heap, then it makes a copy when
// toByteArray
@@ -307,14 +342,14 @@ public String toStringXML(boolean bWithAttachmentContent, boolean bWithVersions,
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
XMLWriter wr = new XMLWriter(baos,
- new OutputFormat("", true, context.getWiki().getEncoding()));
+ new OutputFormat("", true, getXContext().getWiki().getEncoding()));
Document doc = new DOMDocument();
wr.writeDocumentStart(doc);
- toXML(wr, bWithAttachmentContent, bWithVersions, context);
+ toXML(wr, bWithAttachmentContent, bWithVersions, getXContext());
wr.writeDocumentEnd(doc);
byte[] array = baos.toByteArray();
baos = null;
- return new String(array, context.getWiki().getEncoding());
+ return new String(array, getXContext().getWiki().getEncoding());
} catch (IOException e) {
e.printStackTrace();
return "";
@@ -388,10 +423,9 @@ public void toXML(XMLWriter wr, boolean bWithAttachmentContent, boolean bWithVer
if (bWithAttachmentContent) {
el = new DOMElement("content");
// We need to make sure content is loaded
- loadContent(context);
- XWikiAttachmentContent acontent = getAttachment_content();
+ XWikiAttachmentContent acontent = loadContent();
if (acontent != null) {
- wr.writeBase64(el, getAttachment_content().getContentInputStream());
+ wr.writeBase64(el, acontent.getContentInputStream());
} else {
el.addText("");
wr.write(el);
@@ -400,7 +434,7 @@ public void toXML(XMLWriter wr, boolean bWithAttachmentContent, boolean bWithVer
if (bWithVersions) {
// We need to make sure content is loaded
- XWikiAttachmentArchive aarchive = loadArchive(context);
+ XWikiAttachmentArchive aarchive = loadArchive();
if (aarchive != null) {
el = new DOMElement("versions");
try {
@@ -464,17 +498,14 @@ public void fromXML(Element docel) throws XWikiException {
setAuthor(docel.element("author").getText());
setVersion(docel.element("version").getText());
setComment(docel.element("comment").getText());
-
String sdate = docel.element("date").getText();
Date date = new Date(Long.parseLong(sdate));
setDate(date);
-
- Element contentel = docel.element("content");
- if (contentel != null) {
- String base64content = contentel.getText();
- byte[] content = Base64.decodeBase64(base64content.getBytes());
- setContent(content);
- }
+ Optional.ofNullable(docel.element("content"))
+ .map(el -> el.getText().trim())
+ .filter(content -> !content.isEmpty())
+ .map(content -> Base64.decodeBase64(content.getBytes()))
+ .ifPresent(this::setContent);
Element archiveel = docel.element("versions");
if (archiveel != null) {
String archive = archiveel.getText();
@@ -556,7 +587,6 @@ public void setArchive(Archive archive) {
this.attachment_archive = new XWikiAttachmentArchive();
this.attachment_archive.setAttachment(this);
}
-
this.attachment_archive.setRCSArchive(archive);
}
@@ -565,8 +595,9 @@ public void setArchive(String data) throws XWikiException {
this.attachment_archive = new XWikiAttachmentArchive();
this.attachment_archive.setAttachment(this);
}
-
- this.attachment_archive.setArchive(data.getBytes());
+ if (data != null) {
+ this.attachment_archive.setArchive(data.getBytes());
+ }
}
public synchronized Version[] getVersions() {
@@ -603,16 +634,16 @@ public synchronized List getVersionList() throws XWikiException {
*
* @param data
* a byte array with the binary content of the attachment
- * @deprecated use {@link #setContent(java.io.InputStream, int)} instead
+ * @deprecated use {@link #setContent(java.io.InputStream)} instead
*/
@Deprecated
public void setContent(byte[] data) {
- if (this.attachment_content == null) {
- this.attachment_content = new XWikiAttachmentContent();
- this.attachment_content.setAttachment(this);
+ data = (data != null) ? data : new byte[0];
+ try (InputStream is = new ByteArrayInputStream(data)) {
+ setContent(is);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to set attachment content from byte array", e);
}
-
- this.attachment_content.setContent(data);
}
/**
@@ -624,15 +655,11 @@ public void setContent(byte[] data) {
* the length in byte to read
* @throws IOException
* when an error occurs during streaming operation
- * @since 2.3M2
+ * @deprecated use {@link #setContent(java.io.InputStream)} instead
*/
+ @Deprecated
public void setContent(InputStream is, int length) throws IOException {
- if (this.attachment_content == null) {
- this.attachment_content = new XWikiAttachmentContent();
- this.attachment_content.setAttachment(this);
- }
-
- this.attachment_content.setContent(is, length);
+ setContent(is);
}
/**
@@ -645,55 +672,45 @@ public void setContent(InputStream is, int length) throws IOException {
* @since 2.6M1
*/
public void setContent(InputStream is) throws IOException {
- if (this.attachment_content == null) {
- this.attachment_content = new XWikiAttachmentContent(this);
+ if (attachment_content == null) {
+ attachment_content = new XWikiAttachmentContent();
+ attachment_content.setAttachment(this);
+ }
+ if (is != null) {
+ attachment_content.setContent(is);
}
-
- this.attachment_content.setContent(is);
}
- public void loadContent(XWikiContext context) throws XWikiException {
+ public XWikiAttachmentContent loadContent() throws XWikiException {
if (this.attachment_content == null) {
- try {
- context.getWiki().getAttachmentStore().loadAttachmentContent(this, context, true);
- } catch (Exception ex) {
- LOG.warn(String.format("Failed to load content for attachment [%s@%s]. "
- + "This attachment is broken, please consider re-uploading it. " + "Internal error: %s",
- getFilename(), (this.doc != null) ? this.doc.getFullName() : "",
- ex.getMessage()));
- }
+ getAttachmentStore().loadAttachmentContent(this, getXContext(), true);
}
+ return this.attachment_content;
}
- public XWikiAttachmentArchive loadArchive(XWikiContext context) throws XWikiException {
+ public XWikiAttachmentArchive loadArchive() throws XWikiException {
if (this.attachment_archive == null) {
- try {
- this.attachment_archive = context.getWiki().getAttachmentVersioningStore().loadArchive(this,
- context, true);
- } catch (Exception ex) {
- LOG.warn(String.format("Failed to load archive for attachment [%s@%s]. "
- + "This attachment is broken, please consider re-uploading it. " + "Internal error: %s",
- getFilename(), (this.doc != null) ? this.doc.getFullName() : "",
- ex.getMessage()));
- }
+ this.attachment_archive = getAttachmentStore().getVersioningStore()
+ .loadArchive(this, true);
}
-
return this.attachment_archive;
}
- public void updateContentArchive(XWikiContext context) throws XWikiException {
+ public void updateContentArchive() throws XWikiException {
if (this.attachment_content == null) {
return;
}
+ loadArchive().updateArchive();
+ }
- // XWikiAttachmentArchive no longer uses the byte array passed as it's first parameter making it
- // redundant.
- loadArchive(context).updateArchive(null, context);
+ public String getMimeType() {
+ return getMimeType(getXContext());
}
+ @Deprecated
public String getMimeType(XWikiContext context) {
// Choose the right content type
- String mimetype = context.getEngineContext().getMimeType(getFilename().toLowerCase());
+ String mimetype = getXContext().getEngineContext().getMimeType(getFilename().toLowerCase());
if (mimetype != null) {
return mimetype;
} else {
@@ -701,6 +718,11 @@ public String getMimeType(XWikiContext context) {
}
}
+ public boolean isImage() {
+ return isImage(getXContext());
+ }
+
+ @Deprecated
public boolean isImage(XWikiContext context) {
String contenttype = getMimeType(context);
if (contenttype.startsWith("image/")) {
@@ -712,11 +734,31 @@ public boolean isImage(XWikiContext context) {
public XWikiAttachment getAttachmentRevision(String rev, XWikiContext context)
throws XWikiException {
- if (StringUtils.equals(rev, this.getVersion())) {
+ if (Objects.equals(rev, this.getVersion())) {
return this;
}
+ return loadArchive().getRevision(rev);
+ }
+
+ @Override
+ public String toString() {
+ return "XWikiAttachment["
+ + "doc=" + (getDoc() != null ? getDoc().getFullName() : "") + ", "
+ + "filename=" + getFilename() + ", "
+ + "version=" + getVersion() + "]";
+ }
+
+ private XWikiAttachmentStoreInterface getAttachmentStore() {
+ return getBeanFactory().getBean(XWikiProvider.class)
+ .get().orElseThrow(IllegalStateException::new)
+ .getAttachmentStore();
+ }
- return loadArchive(context).getRevision(this, rev, context);
+ private XWikiContext getXContext() {
+ return getBeanFactory().getBean(Execution.class)
+ .getContext()
+ .get(XWIKI_CONTEXT)
+ .orElseThrow(IllegalStateException::new);
}
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentArchive.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentArchive.java
index 292cb9327..d37f9528e 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentArchive.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentArchive.java
@@ -21,22 +21,27 @@
package com.xpn.xwiki.doc;
+import static com.celements.spring.context.SpringContextProvider.*;
+
import java.io.ByteArrayInputStream;
import java.util.Date;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.rcs.Archive;
import org.suigeneris.jrcs.rcs.Version;
import org.suigeneris.jrcs.rcs.impl.Node;
import org.suigeneris.jrcs.util.ToString;
-import com.xpn.xwiki.XWikiContext;
+import com.celements.store.att.AttachmentContentPolicy;
import com.xpn.xwiki.XWikiException;
public class XWikiAttachmentArchive implements Cloneable {
- private static final Log LOG = LogFactory.getLog(XWikiAttachmentArchive.class);
+ private static final Logger LOG = LoggerFactory.getLogger(XWikiAttachmentArchive.class);
private XWikiAttachment attachment;
@@ -87,13 +92,6 @@ public void setRCSArchive(Archive archive) {
}
public byte[] getArchive() throws XWikiException {
- return getArchive(null);
- }
-
- public byte[] getArchive(XWikiContext context) throws XWikiException {
- if ((this.archive == null) && (context != null)) {
- updateArchive(this.attachment.getContent(context), context);
- }
if (this.archive == null) {
return new byte[0];
} else {
@@ -129,11 +127,12 @@ public void setArchive(byte[] data) throws XWikiException {
* the XWikiContext for the request used to load the correct attachment content from the
* database.
*/
- public void updateArchive(byte[] data, XWikiContext context) throws XWikiException {
+ public void updateArchive() throws XWikiException {
try {
this.attachment.incrementVersion();
this.attachment.setDate(new Date());
- String sdata = this.attachment.toStringXML(true, false, context);
+ boolean includeContent = getAttachmentContentPolicy().includeInArchive();
+ String sdata = this.attachment.toStringXML(includeContent, false);
Object[] lines = ToString.stringToArray(sdata);
if (this.archive != null) {
@@ -168,34 +167,37 @@ public Version[] getVersions() {
return versions;
}
- public XWikiAttachment getRevision(XWikiAttachment attachment, String rev, XWikiContext context)
- throws XWikiException {
- try {
- Archive archive = getRCSArchive();
-
- if (archive == null) {
- return null;
- }
+ public XWikiAttachment getRevision(String rev) throws XWikiException {
+ if ((rev == null) || (archive == null)) {
+ return null;
+ }
+ return getRevision(archive.getRevisionVersion(rev));
+ }
- Version v = archive.getRevisionVersion(rev);
- if (v == null) {
+ public XWikiAttachment getRevision(Version v) throws XWikiException {
+ try {
+ if (Objects.equals(v, attachment.getRCSVersion())) {
+ return attachment;
+ } else if ((v == null) || (archive == null)) {
return null;
}
- Object[] lines = archive.getRevision(v);
- StringBuffer content = new StringBuffer();
- for (int i = 0; i < lines.length; i++) {
- String line = lines[i].toString();
- content.append(line);
- if (i != (lines.length - 1)) {
- content.append("\n");
- }
- }
-
- String scontent = content.toString();
+ String xml = Stream.of(archive.getRevision(v))
+ .map(Object::toString)
+ .collect(Collectors.joining("\n"));
XWikiAttachment revattach = new XWikiAttachment();
- revattach.fromXML(scontent);
+ revattach.fromXML(xml);
revattach.setDoc(attachment.getDoc());
- revattach.setVersion(rev);
+ revattach.setVersion(v.toString());
+ /*
+ * If the RCS archive is loaded from Hibernate (legacy), the content is already injected
+ * above by fromXML.
+ * If an alternative content storage is used (e.g. S3), this loads the content here.
+ * It is expected that AttachmentContentStore.loadContent impl can resolve the correct
+ * revision based solely on attachment metadata (doc, filename, version).
+ */
+ if (revattach.getAttachment_content() == null) {
+ revattach.loadContent();
+ }
return revattach;
} catch (Exception e) {
Object[] args = { attachment.getFilename() };
@@ -204,4 +206,8 @@ public XWikiAttachment getRevision(XWikiAttachment attachment, String rev, XWiki
"Exception while manipulating the archive for file {0}", e, args);
}
}
+
+ private AttachmentContentPolicy getAttachmentContentPolicy() {
+ return getBeanFactory().getBean(AttachmentContentPolicy.class);
+ }
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentContent.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentContent.java
index 13945672b..322bd5837 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentContent.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiAttachmentContent.java
@@ -160,13 +160,9 @@ public byte[] getContent() {
*/
@Deprecated
public void setContent(byte[] content) {
- try {
- byte[] internalContent = {};
- if (content != null) {
- internalContent = content;
- }
-
- this.setContent(new ByteArrayInputStream(internalContent));
+ content = (content != null) ? content : new byte[0];
+ try (InputStream in = new ByteArrayInputStream(content)) {
+ this.setContent(in);
} catch (IOException e) {
throw new RuntimeException("Failed to copy data to storage.", e);
}
@@ -220,23 +216,6 @@ public InputStream getContentInputStream() {
}
}
- /**
- * Set the content of the attachment from a portion of an InputStream.
- *
- * @param is
- * the input stream that will be read
- * @param len
- * the number of bytes to read from the beginning of the stream
- * @throws IOException
- * when an error occurs during streaming operation
- * @since 2.3M2
- */
- public void setContent(InputStream is, int len) throws IOException {
- // TODO Fix so this sends a EOS when the limit is reached.
- // this.setContent(new LimitedInputStream(is, ((long) len)));
- this.setContent(is);
- }
-
/**
* Set the content of the attachment from an InputStream.
*
@@ -250,7 +229,6 @@ public void setContent(InputStream is) throws IOException {
this.newFileItem();
IOUtils.copy(is, this.file.getOutputStream());
this.setContentDirty(true);
-
this.attachment.setFilesize(this.getSize());
}
@@ -259,6 +237,11 @@ public void setContent(InputStream is) throws IOException {
* @since 2.3M2
*/
public int getSize() {
- return (int) this.file.getSize();
+ long size = file.getSize();
+ if (size <= Integer.MAX_VALUE) {
+ return (int) size;
+ } else {
+ throw new IllegalStateException("Attachment size " + size + " exceeds max value");
+ }
}
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
index 66432ef77..c332f2b1e 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
@@ -3428,10 +3428,15 @@ public void copyAttachments(XWikiDocument sourceDocument) {
setContentDirty(true);
}
+ @Deprecated
public void loadAttachments(XWikiContext context) throws XWikiException {
+ loadAttachments();
+ }
+
+ public void loadAttachments() throws XWikiException {
for (XWikiAttachment attachment : getAttachmentList()) {
- attachment.loadContent(context);
- attachment.loadArchive(context);
+ attachment.loadContent();
+ attachment.loadArchive();
}
}
@@ -5795,8 +5800,8 @@ private void refactorDocumentLinks(DocumentReference oldDocumentReference,
*/
public XWikiDocument copyDocument(DocumentReference newDocumentReference, XWikiContext context)
throws XWikiException {
- loadAttachments(context);
- loadArchive(context);
+ loadAttachments();
+ getDocumentArchive();
XWikiDocument newdoc = duplicate(newDocumentReference);
newdoc.setOriginalDocument(null);
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java
index 92ed6cd85..80939cd06 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiPatch.java
@@ -23,8 +23,8 @@
import java.util.Arrays;
import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.util.ToString;
import com.xpn.xwiki.XWikiContext;
@@ -41,7 +41,7 @@
public class XWikiPatch {
/** Logger. */
- private static final Log LOG = LogFactory.getLog(XWikiPatch.class);
+ private static final Logger LOG = LoggerFactory.getLogger(XWikiPatch.class);
/** string serialization for patch. */
private String content;
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java
index 515d2f8d5..486cd8a5b 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/doc/rcs/XWikiRCSArchive.java
@@ -24,13 +24,12 @@
import java.util.BitSet;
import java.util.Collection;
import java.util.Date;
-import java.util.Iterator;
import java.util.List;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.net.URLCodec;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.diff.PatchFailedException;
import org.suigeneris.jrcs.rcs.Archive;
import org.suigeneris.jrcs.rcs.InvalidFileFormatException;
@@ -56,7 +55,7 @@
public class XWikiRCSArchive extends Archive {
/** logger. */
- private static final Log LOG = LogFactory.getLog(XWikiRCSArchive.class);
+ private static final Logger LOG = LoggerFactory.getLogger(XWikiRCSArchive.class);
/**
* Used to serialize {@link XWikiDocumentArchive}.
@@ -85,8 +84,8 @@ public XWikiRCSArchive(Collection nodeInfos, XWikiContext cont
nodes.put(node.getVersion(), node);
}
XWikiJRCSNode last = null;
- for (Iterator it = nodes.keySet().iterator(); it.hasNext();) {
- Version ver = (Version) it.next();
+ for (Object element : nodes.keySet()) {
+ Version ver = (Version) element;
XWikiJRCSNode node = (XWikiJRCSNode) nodes.get(ver);
if (last != null) {
last.setRCSNext(node);
@@ -288,8 +287,8 @@ public void patch(List original, boolean annotate)
public Collection getNodes(long docId)
throws NodeNotFoundException, InvalidFileFormatException, PatchFailedException {
Collection result = new ArrayList(nodes.size());
- for (Iterator it = nodes.values().iterator(); it.hasNext();) {
- XWikiJRCSNode node = new XWikiJRCSNode((Node) it.next());
+ for (Object element : nodes.values()) {
+ XWikiJRCSNode node = new XWikiJRCSNode((Node) element);
XWikiRCSNodeInfo nodeInfo = new XWikiRCSNodeInfo();
nodeInfo.setId(new XWikiRCSNodeId(docId, node.getVersion()));
nodeInfo.setDiff(node.isDiff());
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentContentStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentContentStore.java
new file mode 100644
index 000000000..a2d1f5e23
--- /dev/null
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentContentStore.java
@@ -0,0 +1,32 @@
+package com.xpn.xwiki.store;
+
+import javax.validation.constraints.NotEmpty;
+
+import org.xwiki.component.annotation.ComponentRole;
+
+import com.xpn.xwiki.doc.XWikiAttachment;
+import com.xpn.xwiki.doc.XWikiAttachmentContent;
+
+@ComponentRole
+public interface AttachmentContentStore {
+
+ @NotEmpty
+ String getStoreName();
+
+ void saveContent(XWikiAttachmentContent content) throws AttachmentContentStoreException;
+
+ void loadContent(XWikiAttachmentContent content) throws AttachmentContentStoreException;
+
+ void deleteContent(XWikiAttachment attachment) throws AttachmentContentStoreException;
+
+ void deleteContent(XWikiAttachmentContent content) throws AttachmentContentStoreException;
+
+ public static class AttachmentContentStoreException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public AttachmentContentStoreException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentVersioningStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentVersioningStore.java
index b3994f2aa..baf47cd75 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentVersioningStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/AttachmentVersioningStore.java
@@ -21,7 +21,6 @@
import org.xwiki.component.annotation.ComponentRole;
-import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiAttachmentArchive;
@@ -35,21 +34,20 @@
@ComponentRole
public interface AttachmentVersioningStore {
+ boolean hasVersioning();
+
/**
* Load attachment archive from store.
*
* @return attachment archive. not null. return empty archive if it is not exist in store.
* @param attachment
* The attachment of archive.
- * @param context
- * The current context.
* @param bTransaction
* Should use old transaction (false) or create new (true).
* @throws XWikiException
* If an error occurs.
*/
- XWikiAttachmentArchive loadArchive(XWikiAttachment attachment, XWikiContext context,
- boolean bTransaction)
+ XWikiAttachmentArchive loadArchive(XWikiAttachment attachment, boolean bTransaction)
throws XWikiException;
/**
@@ -57,14 +55,12 @@ XWikiAttachmentArchive loadArchive(XWikiAttachment attachment, XWikiContext cont
*
* @param archive
* The attachment archive to save.
- * @param context
- * The current context.
* @param bTransaction
* Should use old transaction (false) or create new (true).
* @throws XWikiException
* If an error occurs.
*/
- void saveArchive(XWikiAttachmentArchive archive, XWikiContext context, boolean bTransaction)
+ void saveArchive(XWikiAttachmentArchive archive, boolean bTransaction)
throws XWikiException;
/**
@@ -72,13 +68,11 @@ void saveArchive(XWikiAttachmentArchive archive, XWikiContext context, boolean b
*
* @param attachment
* The attachment to delete.
- * @param context
- * The current context.
* @param bTransaction
* Should use old transaction (false) or create new (true).
* @throws XWikiException
* If an error occurs.
*/
- void deleteArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction)
+ void deleteArchive(XWikiAttachment attachment, boolean bTransaction)
throws XWikiException;
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/VoidAttachmentVersioningStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/VoidAttachmentVersioningStore.java
index 1be831505..93c4af4f9 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/VoidAttachmentVersioningStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/VoidAttachmentVersioningStore.java
@@ -33,11 +33,8 @@
import com.xpn.xwiki.doc.XWikiAttachmentArchive;
/**
- * Void store for attachment versioning when it is disabled. ("xwiki.store.attachment.versioning=0"
- * parameter is set in
- * xwiki.cfg) It says what there is only one version of attachment - latest. It doesn't store
- * anything. It is safe to
- * use with any stores.
+ * Void store for attachment versioning when it is disabled. It says what there is only one version
+ * of attachment - latest. It doesn't store anything. It is safe to use with any stores.
*
* @version $Id$
* @since 1.4M2
@@ -60,30 +57,25 @@ public VoidAttachmentVersioningStore(XWikiContext context) {}
*/
public VoidAttachmentVersioningStore() {}
- /**
- * {@inheritDoc}
- */
@Override
- public void deleteArchive(XWikiAttachment attachment, XWikiContext context, boolean transaction)
+ public boolean hasVersioning() {
+ return false;
+ }
+
+ @Override
+ public void deleteArchive(XWikiAttachment attachment, boolean transaction)
throws XWikiException {
// Don't do anything since it's a void implementation.
}
- /**
- * {@inheritDoc}
- */
@Override
- public void saveArchive(XWikiAttachmentArchive archive, XWikiContext context, boolean transaction)
+ public void saveArchive(XWikiAttachmentArchive archive, boolean transaction)
throws XWikiException {
// Don't do anything since it's a void implementation.
}
- /**
- * {@inheritDoc}
- */
@Override
- public XWikiAttachmentArchive loadArchive(XWikiAttachment attachment, XWikiContext context,
- boolean transaction)
+ public XWikiAttachmentArchive loadArchive(XWikiAttachment attachment, boolean transaction)
throws XWikiException {
XWikiAttachmentArchive archive = attachment.getAttachment_archive();
if (!(archive instanceof VoidAttachmentArchive)) {
@@ -119,7 +111,7 @@ public VoidAttachmentArchive(XWikiAttachment attachment) {
* {@inheritDoc}
*/
@Override
- public void updateArchive(byte[] data, XWikiContext context) throws XWikiException {
+ public void updateArchive() throws XWikiException {
getAttachment().incrementVersion();
getAttachment().setDate(new Date());
}
@@ -136,8 +128,8 @@ public void setArchive(byte[] data) throws XWikiException {
* {@inheritDoc}
*/
@Override
- public byte[] getArchive(XWikiContext context) throws XWikiException {
- String sdata = getAttachment().toStringXML(true, false, context);
+ public byte[] getArchive() throws XWikiException {
+ String sdata = getAttachment().toStringXML(true, false);
Object[] lines = ToString.stringToArray(sdata);
Archive archive = new Archive(lines, getAttachment().getFilename(),
getAttachment().getVersion());
@@ -164,9 +156,9 @@ public Version[] getVersions() {
* {@inheritDoc}
*/
@Override
- public XWikiAttachment getRevision(XWikiAttachment attachment, String rev, XWikiContext context)
+ public XWikiAttachment getRevision(Version v)
throws XWikiException {
- return (attachment.getVersion().equals(rev)) ? attachment : null;
+ return (getAttachment().getVersion().equals(v.toString())) ? getAttachment() : null;
}
/**
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java
index da634e004..8cb020649 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java
@@ -57,4 +57,9 @@ void deleteXWikiAttachment(XWikiAttachment attachment, boolean parentUpdate, XWi
boolean bTransaction) throws XWikiException;
void cleanUp(XWikiContext context);
+
+ AttachmentContentStore getContentStore();
+
+ AttachmentVersioningStore getVersioningStore();
+
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java
index ae7487cb8..57dd425fc 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java
@@ -1,24 +1,37 @@
package com.xpn.xwiki.store;
+import static com.celements.common.lambda.LambdaExceptionUtil.*;
+import static com.celements.spring.context.SpringContextProvider.*;
+
import java.util.List;
+import java.util.Optional;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.Query;
import org.hibernate.Session;
import org.xwiki.component.annotation.Component;
+import com.celements.store.StoreFactory;
+import com.google.common.base.Suppliers;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiAttachmentContent;
import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.store.hibernate.HibernateAttachmentContentStore;
@Component
public class XWikiHibernateAttachmentStore extends XWikiHibernateBaseStore
implements XWikiAttachmentStoreInterface {
- private static final Log log = LogFactory.getLog(XWikiHibernateAttachmentStore.class);
+ private final Supplier contentStore = Suppliers
+ .memoize(StoreFactory::getAttachmentContentStore);
+ private final Supplier> contentStoreFallback = Suppliers
+ .memoize(() -> Optional.of(getBeanFactory()
+ .getBean(HibernateAttachmentContentStore.STORE_NAME, AttachmentContentStore.class))
+ .filter(store -> !store.getStoreName().equals(contentStore.get().getStoreName())));
+ private final Supplier versioningStore = Suppliers
+ .memoize(StoreFactory::getAttachmentVersioningStore);
/**
* Empty constructor needed for component manager.
@@ -27,69 +40,47 @@ public XWikiHibernateAttachmentStore() {}
@Override
public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context,
- boolean bTransaction)
- throws XWikiException {
+ boolean bTransaction) throws XWikiException {
saveAttachmentContent(attachment, true, context, bTransaction);
}
@Override
public void saveAttachmentContent(XWikiAttachment attachment, boolean parentUpdate,
- XWikiContext context,
- boolean bTransaction) throws XWikiException {
+ XWikiContext context, boolean bTransaction) throws XWikiException {
+ String currentDb = context.getDatabase();
try {
XWikiAttachmentContent content = attachment.getAttachment_content();
if (content.isContentDirty()) {
- attachment.updateContentArchive(context);
+ attachment.updateContentArchive();
+ }
+ var attWiki = attachment.getWikiReference();
+ if (attWiki != null) {
+ context.setDatabase(attWiki.getName());
}
if (bTransaction) {
- checkHibernate(context);
- bTransaction = beginTransaction(context);
+ bTransaction = beginTransaction(attWiki);
}
- Session session = getSession(context);
-
- String db = context.getDatabase();
- String attachdb = (attachment.getDoc() == null) ? null : attachment.getDoc().getDatabase();
- try {
- if (attachdb != null) {
- context.setDatabase(attachdb);
- }
-
- Query query = session.createQuery(
- "select attach.id from XWikiAttachmentContent as attach where attach.id = :id");
- query.setLong("id", content.getId());
- if (query.uniqueResult() == null) {
- session.save(content);
- } else {
- session.update(content);
- }
-
- if (attachment.getAttachment_archive() == null) {
- attachment.loadArchive(context);
- }
- context.getWiki().getAttachmentVersioningStore().saveArchive(
- attachment.getAttachment_archive(),
- context, false);
-
- if (parentUpdate) {
- context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, true);
- }
-
- } finally {
- context.setDatabase(db);
+ getContentStore().saveContent(content);
+ if (attachment.getAttachment_archive() == null) {
+ attachment.loadArchive();
+ }
+ getVersioningStore().saveArchive(attachment.getAttachment_archive(), false);
+ if (parentUpdate) {
+ context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, true);
}
-
if (bTransaction) {
- endTransaction(context, true);
+ endTransaction(true);
}
} catch (Exception e) {
- Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+ Object[] args = { attachment };
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_ATTACHMENT,
- "Exception while saving attachment {0} of document {1}", e, args);
+ "Exception while saving {0}", e, args);
} finally {
+ context.setDatabase(currentDb);
try {
if (bTransaction) {
- endTransaction(context, false);
+ endTransaction(false);
}
} catch (Exception e) {}
}
@@ -98,15 +89,15 @@ public void saveAttachmentContent(XWikiAttachment attachment, boolean parentUpda
@Override
public void saveAttachmentsContent(List attachments, XWikiDocument doc,
- boolean bParentUpdate,
- XWikiContext context, boolean bTransaction) throws XWikiException {
+ boolean bParentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
if (attachments == null) {
return;
}
try {
if (bTransaction) {
- checkHibernate(context);
- bTransaction = beginTransaction(context);
+ bTransaction = beginTransaction(attachments.stream()
+ .map(XWikiAttachment::getWikiReference)
+ .findFirst().orElse(null));
}
for (XWikiAttachment att : attachments) {
saveAttachmentContent(att, false, context, false);
@@ -121,7 +112,7 @@ public void saveAttachmentsContent(List attachments, XWikiDocum
} finally {
try {
if (bTransaction) {
- endTransaction(context, false);
+ endTransaction(false);
}
} catch (Exception e) {}
}
@@ -130,45 +121,39 @@ public void saveAttachmentsContent(List attachments, XWikiDocum
@Override
public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context,
- boolean bTransaction)
- throws XWikiException {
+ boolean bTransaction) throws XWikiException {
+ String currentDb = context.getDatabase();
try {
+ var attWiki = attachment.getWikiReference();
+ if (attWiki != null) {
+ context.setDatabase(attWiki.getName());
+ }
if (bTransaction) {
- checkHibernate(context);
- bTransaction = beginTransaction(false, context);
+ bTransaction = beginTransaction(attWiki);
}
- Session session = getSession(context);
-
- String db = context.getDatabase();
- String attachdb = (attachment.getDoc() == null) ? null : attachment.getDoc().getDatabase();
+ XWikiAttachmentContent content = new XWikiAttachmentContent(attachment);
+ attachment.setAttachment_content(content);
try {
- if (attachdb != null) {
- context.setDatabase(attachdb);
- }
- XWikiAttachmentContent content = new XWikiAttachmentContent(attachment);
- attachment.setAttachment_content(content);
- session.load(content, new Long(content.getId()));
-
- // Hibernate calls setContent which causes isContentDirty to be true. This is not what we
- // want.
- content.setContentDirty(false);
-
- } finally {
- context.setDatabase(db);
+ getContentStore().loadContent(content);
+ } catch (Exception e) {
+ // content load failed, try legacy fallback store first before rethrowing
+ contentStoreFallback.get().ifPresent(rethrowConsumer(s -> s.loadContent(content)));
+ contentStoreFallback.get().orElseThrow(() -> e);
}
-
+ content.setContentDirty(false);
if (bTransaction) {
- endTransaction(context, false, false);
+ endTransaction(false);
}
} catch (Exception e) {
- Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+ Object[] args = { attachment };
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_ATTACHMENT,
- "Exception while loading attachment {0} of document {1}", e, args);
+ "Exception while loading {0}", e, args);
} finally {
+ context.setDatabase(currentDb);
try {
if (bTransaction) {
- endTransaction(context, false, false);
+ endTransaction(false);
}
} catch (Exception e) {}
}
@@ -176,96 +161,80 @@ public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext conte
@Override
public void deleteXWikiAttachment(XWikiAttachment attachment, XWikiContext context,
- boolean bTransaction)
- throws XWikiException {
+ boolean bTransaction) throws XWikiException {
deleteXWikiAttachment(attachment, true, context, bTransaction);
}
@Override
public void deleteXWikiAttachment(XWikiAttachment attachment, boolean parentUpdate,
- XWikiContext context,
- boolean bTransaction) throws XWikiException {
+ XWikiContext context, boolean bTransaction) throws XWikiException {
+ String currentDb = context.getDatabase();
try {
+ var attWiki = attachment.getWikiReference();
+ if (attWiki != null) {
+ context.setDatabase(attWiki.getName());
+ }
if (bTransaction) {
- checkHibernate(context);
- bTransaction = beginTransaction(context);
+ bTransaction = beginTransaction(attWiki);
}
-
- Session session = getSession(context);
-
- String db = context.getDatabase();
- String attachdb = (attachment.getDoc() == null) ? null : attachment.getDoc().getDatabase();
- try {
- if (attachdb != null) {
- context.setDatabase(attachdb);
- }
-
- // Delete the three attachment entries
- try {
- loadAttachmentContent(attachment, context, false);
- try {
- session.delete(attachment.getAttachment_content());
- } catch (Exception e) {
- if (log.isWarnEnabled()) {
- log.warn("Error deleting attachment content " + attachment.getFilename() + " of doc "
- + attachment.getDoc().getFullName());
+ Session session = getSession();
+ // delete attachment content
+ Stream.of(Optional.of(getContentStore()), contentStoreFallback.get())
+ .flatMap(Optional::stream).forEach(store -> {
+ try {
+ store.deleteContent(attachment);
+ } catch (Exception e) {
+ logger.info("Error deleting content for {}", attachment);
}
- }
- } catch (Exception e) {
- if (log.isWarnEnabled()) {
- log.warn("Error loading attachment content when deleting attachment "
- + attachment.getFilename() + " of doc " + attachment.getDoc().getFullName());
- }
- }
-
- context.getWiki().getAttachmentVersioningStore().deleteArchive(attachment, context, false);
-
- try {
- session.delete(attachment);
- } catch (Exception e) {
- if (log.isWarnEnabled()) {
- log.warn("Error deleting attachment meta data " + attachment.getFilename() + " of doc "
- + attachment.getDoc().getFullName());
- }
- }
-
- } finally {
- context.setDatabase(db);
+ });
+ // delete attachment archive
+ getVersioningStore().deleteArchive(attachment, false);
+ // delete attachment meta data
+ try {
+ session.delete(attachment);
+ } catch (Exception e) {
+ logger.warn("Error deleting meta data for {}", attachment);
}
-
+ // update parent document
try {
if (parentUpdate) {
- List list = attachment.getDoc().getAttachmentList();
- for (int i = 0; i < list.size(); i++) {
- XWikiAttachment attach = list.get(i);
- if (attachment.getFilename().equals(attach.getFilename())) {
- list.remove(i);
+ var iter = attachment.getDoc().getAttachmentList().iterator();
+ while (iter.hasNext()) {
+ if (attachment.getFilename().equals(iter.next().getFilename())) {
+ iter.remove();
break;
}
}
context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, false);
}
} catch (Exception e) {
- if (log.isWarnEnabled()) {
- log.warn("Error updating document when deleting attachment " + attachment.getFilename()
- + " of doc " + attachment.getDoc().getFullName());
- }
+ logger.warn("Error updating document when deleting {}", attachment);
}
-
if (bTransaction) {
- endTransaction(context, true);
+ endTransaction(true);
}
} catch (Exception e) {
- Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+ Object[] args = { attachment };
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
XWikiException.ERROR_XWIKI_STORE_HIBERNATE_DELETING_ATTACHMENT,
- "Exception while deleting attachment {0} of document {1}", e, args);
+ "Exception while deleting {0}", e, args);
} finally {
+ context.setDatabase(currentDb);
try {
if (bTransaction) {
- endTransaction(context, false);
+ endTransaction(false);
}
} catch (Exception e) {}
}
}
+
+ @Override
+ public AttachmentContentStore getContentStore() {
+ return contentStore.get();
+ }
+
+ @Override
+ public AttachmentVersioningStore getVersioningStore() {
+ return versioningStore.get();
+ }
}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
index d0cf6d7a3..0ca542bf0 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
@@ -1,5 +1,6 @@
package com.xpn.xwiki.store;
+import static com.celements.execution.XWikiExecutionProp.*;
import static com.celements.logging.LogUtils.*;
import static com.google.common.base.Preconditions.*;
@@ -24,6 +25,7 @@
import org.xwiki.component.annotation.Requirement;
import org.xwiki.component.phase.Initializable;
import org.xwiki.component.phase.InitializationException;
+import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.context.Execution;
import org.xwiki.context.ExecutionContext;
import org.xwiki.model.reference.WikiReference;
@@ -55,6 +57,9 @@ public class XWikiHibernateBaseStore implements Initializable {
@Requirement
protected XWikiConfigSource xwikiCfg;
+ @Requirement("allproperties")
+ protected ConfigurationSource cfgSrc;
+
private String hibpath = DEFAULT_CFG_PATH;
/**
@@ -1006,6 +1011,10 @@ protected final ExecutionContext getEContext() {
return execution.getContext();
}
+ protected XWikiContext getXContext() {
+ return getEContext().get(XWIKI_CONTEXT).orElseThrow(IllegalStateException::new);
+ }
+
protected WikiReference getWikiRef(XWikiContext context) {
return Strings.isNullOrEmpty(context.getDatabase()) ? null
: new WikiReference(context.getDatabase());
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java
index ba46725eb..88c72a128 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/XWikiHibernateVersioningStore.java
@@ -24,11 +24,11 @@
import java.util.Iterator;
import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.suigeneris.jrcs.rcs.Version;
import org.xwiki.component.annotation.Component;
@@ -50,7 +50,7 @@ public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore
implements XWikiVersioningStoreInterface {
/** Logger. */
- private static final Log LOG = LogFactory.getLog(XWikiHibernateVersioningStore.class);
+ private static final Logger LOG = LoggerFactory.getLogger(XWikiHibernateVersioningStore.class);
/** Colon symbol. */
private static final String COLON = ":";
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentContentStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentContentStore.java
new file mode 100644
index 000000000..6f3463129
--- /dev/null
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentContentStore.java
@@ -0,0 +1,73 @@
+package com.xpn.xwiki.store.hibernate;
+
+import javax.inject.Named;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.Session;
+import org.springframework.stereotype.Component;
+
+import com.xpn.xwiki.doc.XWikiAttachment;
+import com.xpn.xwiki.doc.XWikiAttachmentContent;
+import com.xpn.xwiki.store.AttachmentContentStore;
+import com.xpn.xwiki.store.XWikiHibernateBaseStore;
+
+@Component
+@Named(HibernateAttachmentContentStore.STORE_NAME)
+public class HibernateAttachmentContentStore extends XWikiHibernateBaseStore
+ implements AttachmentContentStore {
+
+ public static final String STORE_NAME = "store.attachment.content.hibernate";
+
+ @Override
+ public String getStoreName() {
+ return STORE_NAME;
+ }
+
+ @Override
+ public void saveContent(XWikiAttachmentContent content) throws AttachmentContentStoreException {
+ logger.info("saveContent - {}", content.getAttachment());
+ try {
+ Session session = getSession();
+ Query query = session.createQuery(
+ "select attach.id from XWikiAttachmentContent as attach where attach.id = :id");
+ query.setLong("id", content.getId());
+ if (query.uniqueResult() == null) {
+ session.save(content);
+ } else {
+ session.update(content);
+ }
+ } catch (HibernateException e) {
+ throw new AttachmentContentStoreException("Failed saving attachment", e);
+ }
+ }
+
+ @Override
+ public void loadContent(XWikiAttachmentContent content) throws AttachmentContentStoreException {
+ logger.info("loadContent - {}", content.getAttachment());
+ try {
+ Session session = getSession();
+ session.load(content, Long.valueOf(content.getId()));
+ } catch (HibernateException e) {
+ throw new AttachmentContentStoreException("Failed loading attachment", e);
+ }
+ }
+
+ @Override
+ public void deleteContent(XWikiAttachment attachment) throws AttachmentContentStoreException {
+ logger.info("deleteContent - {}", attachment);
+ try {
+ Session session = getSession();
+ session.createQuery("delete from " + XWikiAttachmentContent.class.getName() + " where id = ?")
+ .setLong(0, attachment.getId())
+ .executeUpdate();
+ } catch (Exception e) {
+ throw new AttachmentContentStoreException("Failed deleting attachment", e);
+ }
+ }
+
+ @Override
+ public void deleteContent(XWikiAttachmentContent content) throws AttachmentContentStoreException {
+ deleteContent(content.getAttachment());
+ }
+}
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentRecycleBinStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentRecycleBinStore.java
index 9cfbb1c21..d615ee82d 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentRecycleBinStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentRecycleBinStore.java
@@ -19,6 +19,8 @@
*/
package com.xpn.xwiki.store.hibernate;
+import static com.celements.spring.context.SpringContextProvider.*;
+
import java.util.Date;
import java.util.List;
@@ -30,6 +32,7 @@
import org.hibernate.criterion.Restrictions;
import org.xwiki.component.annotation.Component;
+import com.celements.store.att.AttachmentContentPolicy;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.DeletedAttachment;
@@ -69,8 +72,10 @@ public HibernateAttachmentRecycleBinStore() {}
public void saveToRecycleBin(XWikiAttachment attachment, String deleter, Date date,
XWikiContext context,
boolean bTransaction) throws XWikiException {
+ boolean includeContent = getBeanFactory().getBean(AttachmentContentPolicy.class)
+ .includeInRecycleBin();
final DeletedAttachment trashAtachment = new DeletedAttachment(attachment, deleter, date,
- context);
+ includeContent);
executeWrite(context, bTransaction, session -> {
session.save(trashAtachment);
return null;
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentVersioningStore.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentVersioningStore.java
index 76855034c..6429e4f4e 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentVersioningStore.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/hibernate/HibernateAttachmentVersioningStore.java
@@ -19,12 +19,11 @@
*/
package com.xpn.xwiki.store.hibernate;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.hibernate.ObjectNotFoundException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xwiki.component.annotation.Component;
-import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiAttachmentArchive;
@@ -42,23 +41,27 @@ public class HibernateAttachmentVersioningStore extends XWikiHibernateBaseStore
implements AttachmentVersioningStore {
/** logger. */
- private static final Log LOG = LogFactory.getLog(HibernateAttachmentVersioningStore.class);
+ private static final Logger LOG = LoggerFactory
+ .getLogger(HibernateAttachmentVersioningStore.class);
/**
* Empty constructor needed for component manager.
*/
public HibernateAttachmentVersioningStore() {}
- /**
- * {@inheritDoc}
- */
@Override
- public XWikiAttachmentArchive loadArchive(final XWikiAttachment attachment, XWikiContext context,
- boolean bTransaction) throws XWikiException {
+ public boolean hasVersioning() {
+ return true;
+ }
+
+ @Override
+ public XWikiAttachmentArchive loadArchive(final XWikiAttachment attachment, boolean bTransaction)
+ throws XWikiException {
try {
final XWikiAttachmentArchive archive = new XWikiAttachmentArchive();
archive.setAttachment(attachment);
- executeRead(context, bTransaction, session -> {
+ var wiki = attachment.getWikiReference();
+ executeRead(wiki, bTransaction, session -> {
try {
session.load(archive, archive.getId());
} catch (ObjectNotFoundException e) {
@@ -76,28 +79,22 @@ public XWikiAttachmentArchive loadArchive(final XWikiAttachment attachment, XWik
}
}
- /**
- * {@inheritDoc}
- */
@Override
- public void saveArchive(final XWikiAttachmentArchive archive, XWikiContext context,
- boolean bTransaction)
+ public void saveArchive(final XWikiAttachmentArchive archive, boolean bTransaction)
throws XWikiException {
- executeWrite(context, bTransaction, session -> {
+ var wiki = archive.getAttachment().getWikiReference();
+ executeWrite(wiki, bTransaction, session -> {
session.saveOrUpdate(archive);
return null;
});
}
- /**
- * {@inheritDoc}
- */
@Override
- public void deleteArchive(final XWikiAttachment attachment, final XWikiContext context,
- boolean bTransaction)
+ public void deleteArchive(final XWikiAttachment attachment, boolean bTransaction)
throws XWikiException {
try {
- executeWrite(context, bTransaction, session -> {
+ var wiki = attachment.getWikiReference();
+ executeWrite(wiki, bTransaction, session -> {
XWikiAttachmentArchive archive = new XWikiAttachmentArchive();
archive.setAttachment(attachment);
session.delete(archive);
diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/migration/hibernate/XWikiHibernateMigrationManager.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/migration/hibernate/XWikiHibernateMigrationManager.java
index 0aa42379e..298189a10 100644
--- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/migration/hibernate/XWikiHibernateMigrationManager.java
+++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/store/migration/hibernate/XWikiHibernateMigrationManager.java
@@ -22,8 +22,8 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
@@ -40,7 +40,7 @@
public class XWikiHibernateMigrationManager extends AbstractXWikiMigrationManager {
/** logger */
- protected static final Log LOG = LogFactory.getLog(XWikiHibernateMigrationManager.class);
+ protected static final Logger LOG = LoggerFactory.getLogger(XWikiHibernateMigrationManager.class);
/** {@inheritDoc} */
public XWikiHibernateMigrationManager(XWikiContext context) throws XWikiException {
diff --git a/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/VoidAttachmentVersioningStoreTest.java b/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/VoidAttachmentVersioningStoreTest.java
deleted file mode 100644
index 2a7881d0d..000000000
--- a/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/VoidAttachmentVersioningStoreTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package com.xpn.xwiki.store;
-
-import org.suigeneris.jrcs.rcs.Version;
-
-import com.xpn.xwiki.XWiki;
-import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.doc.XWikiAttachment;
-import com.xpn.xwiki.doc.XWikiAttachmentArchive;
-import com.xpn.xwiki.doc.XWikiDocument;
-import com.xpn.xwiki.store.VoidAttachmentVersioningStore.VoidAttachmentArchive;
-import com.xpn.xwiki.test.AbstractBridgedXWikiComponentTestCase;
-
-/**
- * Unit tests for {@link VoidAttachmentVersioningStore} and {@link VoidAttachmentArchive}.
- *
- * @version $Id$
- */
-public class VoidAttachmentVersioningStoreTest extends AbstractBridgedXWikiComponentTestCase {
-
- AttachmentVersioningStore store;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- XWiki xwiki = new XWiki(false);
- getContext().setWiki(xwiki);
-
- this.store = getComponentManager().lookup(AttachmentVersioningStore.class, "void");
- xwiki.setAttachmentVersioningStore(this.store);
- }
-
- public void testStore() throws XWikiException {
- // is store correctly inited?
- assertEquals(VoidAttachmentVersioningStore.class, this.store.getClass());
- // create doc, attachment & attachment archive
- XWikiDocument doc = new XWikiDocument("Main", "Test");
- XWikiAttachment attachment = new XWikiAttachment(doc, "filename");
- attachment.setContent(new byte[] { 1 });
- attachment.updateContentArchive(getContext());
- // is archive correctly inited and cloneable?
- this.store.saveArchive(attachment.getAttachment_archive(), this.getContext(), true);
- XWikiAttachmentArchive archive = this.store.loadArchive(attachment, this.getContext(), false);
- assertEquals(VoidAttachmentArchive.class, archive.getClass());
- assertEquals(VoidAttachmentArchive.class, archive.clone().getClass());
- assertEquals(archive, this.store.loadArchive(attachment, this.getContext(), true));
-
- this.store.deleteArchive(attachment, getContext(), true);
- }
-
- public void testHistory() throws XWikiException {
- XWikiDocument doc = new XWikiDocument("Main", "Test");
- XWikiAttachment attachment = new XWikiAttachment(doc, "filename");
- // 1.1
- attachment.setContent(new byte[] { 1 });
- attachment.updateContentArchive(this.getContext());
- assertEquals(attachment, attachment.getAttachmentRevision("1.1", this.getContext()));
- // 1.2
- attachment.setContent(new byte[] { 2 });
- attachment.updateContentArchive(this.getContext());
- assertEquals(attachment, attachment.getAttachmentRevision("1.2", this.getContext()));
- // there should be only 1.2 version.
- assertNull(attachment.getAttachmentRevision("1.1", this.getContext()));
- assertNull(attachment.getAttachmentRevision("1.3", this.getContext()));
- assertEquals(1, attachment.getVersions().length);
- assertEquals(new Version(1, 2), attachment.getVersions()[0]);
- }
-}
diff --git a/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/XWikiHibernateStoreTest.java b/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/XWikiHibernateStoreTest.java
index f931e1294..1e2f2f718 100644
--- a/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/XWikiHibernateStoreTest.java
+++ b/celements-xwiki-core/src/test/java/com/xpn/xwiki/store/XWikiHibernateStoreTest.java
@@ -29,6 +29,8 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.xwiki.configuration.ConfigurationSource;
+import org.xwiki.test.MockConfigurationSource;
import com.xpn.xwiki.XWikiConstant;
import com.xpn.xwiki.test.AbstractComponentTest;
@@ -44,7 +46,9 @@ public class XWikiHibernateStoreTest extends AbstractComponentTest {
XWikiHibernateStore store;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
+ var cfgSrc = new MockConfigurationSource();
+ registerComponentMock(ConfigurationSource.class, "allproperties", cfgSrc);
store = Utils.getComponent(XWikiHibernateStore.class);
store.setPath("whatever");
}