Skip to content
3 changes: 2 additions & 1 deletion celements-model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>celements-model</artifactId>
<version>7.0-SNAPSHOT</version>
<description>Celements XWiki</description>
<description>Celements Model</description>
<dependencies>
<dependency>
<groupId>com.celements</groupId>
<artifactId>celements-config-source</artifactId>
<version>7.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.celements</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.celements.common.lambda.LambdaExceptionUtil.*;
import static com.celements.execution.XWikiExecutionProp.*;
import static com.celements.logging.LogUtils.*;
import static com.celements.spring.context.SpringContextProvider.*;
import static com.google.common.base.Preconditions.*;

Expand Down Expand Up @@ -98,7 +99,7 @@ public void onApplicationEvent(CelementsStartedEvent event) {
XWiki xwiki = bootstrapXWiki();
// make XWiki available to all requests via servlet context, see {@link XWikiProvider}
xwikiFuture.complete(xwiki);
LOGGER.info("XWiki initialised");
LOGGER.info("XWiki initialised: {}", defer(xwiki::printConfig));
} catch (Exception exc) {
xwikiFuture.completeExceptionally(exc);
LOGGER.error("Celements bootstrap failed");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.celements.store;

import static com.celements.spring.context.SpringContextProvider.*;

import java.util.Optional;

import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.configuration.ConfigurationSource;

import com.google.common.primitives.Ints;
import com.xpn.xwiki.store.AttachmentContentStore;
import com.xpn.xwiki.store.AttachmentVersioningStore;
import com.xpn.xwiki.store.XWikiAttachmentStoreInterface;
import com.xpn.xwiki.store.XWikiRecycleBinStoreInterface;
import com.xpn.xwiki.store.XWikiStoreInterface;
import com.xpn.xwiki.store.hibernate.HibernateAttachmentContentStore;
import com.xpn.xwiki.web.Utils;

public final class StoreFactory {
Expand All @@ -28,6 +34,30 @@ public static Optional<XWikiRecycleBinStoreInterface> getRecycleBinStore() {
return getOptionalStore(XWikiRecycleBinStoreInterface.class, "celements.store.recyclebin");
}

public static XWikiAttachmentStoreInterface getAttachmentStore() {
try {
String hint = getConfigSource().getProperty("celements.store.attachment");
return getComponentManager().lookup(XWikiAttachmentStoreInterface.class, hint);
} catch (ComponentLookupException exc) {
throw new IllegalStateException("failed looking up attachment store", exc);
}
}

public static AttachmentContentStore getAttachmentContentStore() {
String beanName = getConfigSource().getProperty("celements.store.attachment.content",
HibernateAttachmentContentStore.STORE_NAME);
return getBeanFactory().getBean(beanName, AttachmentContentStore.class);
}

public static AttachmentVersioningStore getAttachmentVersioningStore() {
try {
return getComponentManager().lookup(AttachmentVersioningStore.class,
getConfigSource().getProperty("celements.store.attachment.versioning", "default"));
} catch (ComponentLookupException exc) {
throw new IllegalStateException("failed looking up attachment versioning store", exc);
}
}

private static <T> Optional<T> getOptionalStore(Class<T> type, String key) {
try {
String enabled = getConfigSource().getProperty(key + ".enabled", "false").toLowerCase();
Expand All @@ -42,8 +72,8 @@ private static <T> Optional<T> getOptionalStore(Class<T> 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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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).
* <p>
* 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.
* <p>
* 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);
}

}
39 changes: 23 additions & 16 deletions celements-xwiki-core/src/main/java/com/xpn/xwiki/XWiki.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand All @@ -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.
Expand Down Expand Up @@ -782,7 +793,7 @@ public XWikiAttachmentStoreInterface getAttachmentStore() {
}

public AttachmentVersioningStore getAttachmentVersioningStore() {
return this.attachmentVersioningStore;
return getAttachmentStore().getVersioningStore();
}

public XWikiVersioningStoreInterface getVersioningStore() {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public String getContentAsString(String charset) throws XWikiException {
}

public Version[] getVersions() throws XWikiException {
attachment.loadArchive(getXWikiContext());
attachment.loadArchive();
return attachment.getVersions();
}

Expand All @@ -150,7 +150,7 @@ public Version[] getVersions() throws XWikiException {
* @throws XWikiException
*/
public List<Version> getVersionList() throws XWikiException {
attachment.loadArchive(getXWikiContext());
attachment.loadArchive();
return attachment.getVersionList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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));
}

/**
Expand Down
Loading