use of org.xwiki.observation.ObservationManager in project xwiki-platform by xwiki.
the class XWikiTest method testDeleteDocumentSendsObservationEvents.
/**
* We only verify here that the deleteDocument API calls the Observation component.
*/
public void testDeleteDocumentSendsObservationEvents() throws Exception {
Mock mockListener = mock(EventListener.class);
mockListener.stubs().method("getName").will(returnValue("testlistener"));
DocumentReference ref = new DocumentReference("xwikitest", "Another", "Document");
mockListener.expects(once()).method("getEvents").will(returnValue(Arrays.asList(new DocumentDeletedEvent(ref), new DocumentDeletingEvent(ref))));
ObservationManager om = getComponentManager().getInstance(ObservationManager.class);
om.addListener((EventListener) mockListener.proxy());
XWikiDocument document = new XWikiDocument(new DocumentReference("xwikitest", "Another", "Document"));
document.setContent("the content");
// Not expectation on mock Listener since we're not subscribed to Document save events
this.xwiki.saveDocument(document, getContext());
// Ensure that the onEvent method has been called before and after the deletion
mockListener.expects(once()).method("onEvent").with(isA(DocumentDeletingEvent.class), isA(XWikiDocument.class), isA(XWikiContext.class));
mockListener.expects(once()).method("onEvent").with(isA(DocumentDeletedEvent.class), isA(XWikiDocument.class), isA(XWikiContext.class));
this.xwiki.deleteDocument(document, false, getContext());
}
use of org.xwiki.observation.ObservationManager in project xwiki-platform by xwiki.
the class XWikiHibernateStoreTest method testLocksAreReleasedOnLogout.
@Test
public void testLocksAreReleasedOnLogout() throws Exception {
// Capture the event listener.
ObservationManager observationManager = getMocker().getInstance(ObservationManager.class);
ArgumentCaptor<EventListener> eventListenerCaptor = ArgumentCaptor.forClass(EventListener.class);
verify(observationManager).addListener(eventListenerCaptor.capture());
assertEquals("deleteLocksOnLogoutListener", eventListenerCaptor.getValue().getName());
Query query = mock(Query.class);
when(session.createQuery("delete from XWikiLock as lock where lock.userName=:userName")).thenReturn(query);
when(xcontext.getUserReference()).thenReturn(new DocumentReference("xwiki", "XWiki", "LoggerOutter"));
when(xcontext.getUser()).thenReturn("XWiki.LoggerOutter");
// Fire the logout event.
eventListenerCaptor.getValue().onEvent(new ActionExecutingEvent("logout"), null, xcontext);
verify(query).setString("userName", "XWiki.LoggerOutter");
verify(query).executeUpdate();
verify(this.hibernateStore).beginTransaction();
verify(this.hibernateStore).endTransaction(true);
}
use of org.xwiki.observation.ObservationManager in project xwiki-platform by xwiki.
the class ImportTest method testImportExtension.
/**
* Test the regular document import when the XAR is tagged as extension.
*
* @throws Exception
*/
public void testImportExtension() throws Exception {
ExtensionId extensionId = new ExtensionId("test", "1.0");
XWikiDocument doc1 = new XWikiDocument(new DocumentReference("Test", "Test", "DocImport"));
doc1.setDefaultLanguage("en");
byte[] zipFile = this.createZipFile(new XWikiDocument[] { doc1 }, new String[] { "ISO-8859-1" }, extensionId);
// Store the extension in the local repository
DefaultLocalExtension localExtension = new DefaultLocalExtension(null, extensionId, "xar");
File file = File.createTempFile("temp", ".xar");
FileUtils.writeByteArrayToFile(file, zipFile);
localExtension.setFile(file);
LocalExtensionRepository localeRepository = getComponentManager().getInstance(LocalExtensionRepository.class);
localeRepository.storeExtension(localExtension);
// Listen to extension installed event
Mock extensionListener = mock(EventListener.class);
extensionListener.stubs().method("getEvents").will(returnValue(Arrays.asList(new ExtensionInstalledEvent())));
extensionListener.stubs().method("getName").will(returnValue("extension installed listener"));
extensionListener.expects(once()).method("onEvent");
ObservationManager observationManager = getComponentManager().getInstance(ObservationManager.class);
observationManager.addListener((EventListener) extensionListener.proxy());
// make sure no data is in the packager from the other tests run
this.pack = new Package();
// import and install this document
this.pack.Import(zipFile, getContext());
this.pack.install(getContext());
// check if it is there
XWikiDocument foundDocument = this.xwiki.getDocument(new DocumentReference("Test", "Test", "DocImport"), getContext());
assertFalse(foundDocument.isNew());
XWikiDocument nonExistingDocument = this.xwiki.getDocument(new DocumentReference("Test", "Test", "DocImportNonexisting"), getContext());
assertTrue(nonExistingDocument.isNew());
XWikiDocument foundTranslationDocument = foundDocument.getTranslatedDocument("fr", getContext());
assertSame(foundDocument, foundTranslationDocument);
XWikiDocument doc1Translation = new XWikiDocument(new DocumentReference("Test", "Test", "DocImport"));
doc1Translation.setLanguage("fr");
doc1Translation.setDefaultLanguage("en");
this.xwiki.saveDocument(doc1Translation, getContext());
foundTranslationDocument = foundDocument.getTranslatedDocument("fr", getContext());
assertNotSame(foundDocument, foundTranslationDocument);
// Check that the extension has been registered
InstalledExtensionRepository installedExtensionRepository = getComponentManager().getInstance(InstalledExtensionRepository.class);
assertNotNull(installedExtensionRepository.getInstalledExtension(extensionId));
assertNotNull(installedExtensionRepository.getInstalledExtension(extensionId.getId(), "wiki:" + getContext().getWikiId()));
}
use of org.xwiki.observation.ObservationManager in project xwiki-platform by xwiki.
the class ActivityStreamImpl method init.
@Override
public void init(XWikiContext context) throws XWikiException {
// Lookup the configuration
configuration = Utils.getComponent(ActivityStreamConfiguration.class);
// Listent to Events.
ObservationManager observationManager = Utils.getComponent(ObservationManager.class);
if (observationManager.getListener(getName()) == null) {
observationManager.addListener(this);
}
// Init activitystream cleaner.
ActivityStreamCleaner.getInstance().init(context);
}
use of org.xwiki.observation.ObservationManager in project xwiki-platform by xwiki.
the class XWiki method rollback.
public XWikiDocument rollback(final XWikiDocument tdoc, String rev, XWikiContext context) throws XWikiException {
LOGGER.debug("Rolling back [{}] to version [{}]", tdoc, rev);
// Let's clone rolledbackDoc since we might modify it
XWikiDocument rolledbackDoc = getDocument(tdoc, rev, context).clone();
if ("1".equals(getConfiguration().getProperty("xwiki.store.rollbackattachmentwithdocuments", "1"))) {
// Attachment handling strategy:
// - Two lists: Old Attachments, Current Attachments
// Goals:
// 1. Attachments that are only in OA must be restored from the trash
// 2. Attachments that are only in CA must be sent to the trash
// 3. Attachments that are in both lists should be reverted to the right version
// 4. Gotcha: deleted and re-uploaded attachments should be both trashed and restored.
// Plan:
// - Construct two lists: to restore, to revert
// - Iterate over OA.
// -- If the attachment is not in CA, add it to the restore list
// -- If it is in CA, but the date of the first version of the current attachment is after the date of the
// restored document version, add it the restore & move the current attachment to the recycle bin
// -- Otherwise, add it to the revert list
// - Iterate over CA
// -- If the attachment is not in OA, delete it
List<XWikiAttachment> oldAttachments = rolledbackDoc.getAttachmentList();
List<XWikiAttachment> currentAttachments = tdoc.getAttachmentList();
List<XWikiAttachment> toRestore = new ArrayList<>();
List<XWikiAttachment> toRevert = new ArrayList<>();
// First step, determine what to do with each attachment
LOGGER.debug("Checking attachments");
for (XWikiAttachment oldAttachment : oldAttachments) {
String filename = oldAttachment.getFilename();
XWikiAttachment equivalentAttachment = tdoc.getAttachment(filename);
if (equivalentAttachment == null) {
// Deleted attachment
LOGGER.debug("Deleted attachment: [{}]", filename);
toRestore.add(oldAttachment);
continue;
}
XWikiAttachment equivalentAttachmentRevision = equivalentAttachment.getAttachmentRevision(oldAttachment.getVersion(), context);
// because the nanoseconds component of the passed date is unknown.
if (equivalentAttachmentRevision == null || equivalentAttachmentRevision.getDate().getTime() != oldAttachment.getDate().getTime()) {
// Recreated attachment
LOGGER.debug("Recreated attachment: [{}]", filename);
// If the attachment trash is not available, don't lose the existing attachment
if (getAttachmentRecycleBinStore() != null) {
getAttachmentRecycleBinStore().saveToRecycleBin(equivalentAttachment, context.getUser(), new Date(), context, true);
toRestore.add(oldAttachment);
}
continue;
}
if (!StringUtils.equals(oldAttachment.getVersion(), equivalentAttachment.getVersion())) {
// Updated attachment
LOGGER.debug("Updated attachment: [{}]", filename);
toRevert.add(equivalentAttachment);
}
}
for (XWikiAttachment attachment : currentAttachments) {
if (rolledbackDoc.getAttachment(attachment.getFilename()) == null) {
LOGGER.debug("New attachment: " + attachment.getFilename());
// XWikiDocument#save() is actually the only way to delete an attachment cleanly
rolledbackDoc.getAttachmentsToRemove().add(new XWikiAttachmentToRemove(attachment, true));
}
}
// Revert updated attachments to the old version
for (XWikiAttachment attachmentToRevert : toRevert) {
String oldAttachmentVersion = rolledbackDoc.getAttachment(attachmentToRevert.getFilename()).getVersion();
XWikiAttachment oldAttachmentRevision = attachmentToRevert.getAttachmentRevision(oldAttachmentVersion, context);
if (oldAttachmentRevision == null) {
// Previous version is lost, just leave the current version in place
rolledbackDoc.setAttachment(attachmentToRevert);
continue;
}
// We can't just leave the old version in place, since it will break the revision history, given the
// current implementation, so we set the attachment version to the most recent version, mark the content
// as dirty, and the storage will automatically bump up the version number.
// This is a hack, to be fixed once the storage doesn't take care of updating the history and version,
// and once the current attachment version can point to an existing version from the history.
oldAttachmentRevision.setVersion(attachmentToRevert.getVersion());
oldAttachmentRevision.setMetaDataDirty(true);
oldAttachmentRevision.getAttachment_content().setContentDirty(true);
rolledbackDoc.setAttachment(oldAttachmentRevision);
}
// Restore deleted attachments from the trash
if (getAttachmentRecycleBinStore() != null) {
for (XWikiAttachment attachmentToRestore : toRestore) {
// There might be multiple versions of the attachment in the trash, search for the right one
List<DeletedAttachment> deletedVariants = getAttachmentRecycleBinStore().getAllDeletedAttachments(attachmentToRestore, context, true);
DeletedAttachment correctVariant = null;
for (DeletedAttachment variant : deletedVariants) {
// Reverse chronological order
if (variant.getDate().before(rolledbackDoc.getDate())) {
break;
}
correctVariant = variant;
}
if (correctVariant == null) {
// Not found in the trash, nothing left to do
continue;
}
XWikiAttachment restoredAttachment = correctVariant.restoreAttachment();
XWikiAttachment restoredAttachmentRevision = restoredAttachment.getAttachmentRevision(attachmentToRestore.getVersion(), context);
if (restoredAttachmentRevision != null) {
restoredAttachmentRevision.setAttachment_archive(restoredAttachment.getAttachment_archive());
restoredAttachmentRevision.getAttachment_archive().setAttachment(restoredAttachmentRevision);
restoredAttachmentRevision.setVersion(restoredAttachment.getVersion());
restoredAttachmentRevision.setMetaDataDirty(true);
restoredAttachmentRevision.getAttachment_content().setContentDirty(true);
rolledbackDoc.setAttachment(restoredAttachmentRevision);
} else {
// This particular version is lost, update to the one available
rolledbackDoc.setAttachment(restoredAttachment);
}
}
} else {
// No trash, can't restore. Remove the attachment references, so that the document is not broken
for (XWikiAttachment attachmentToRestore : toRestore) {
rolledbackDoc.getAttachmentList().remove(attachmentToRestore);
}
}
}
// Special treatment for deleted objects
rolledbackDoc.addXObjectsToRemoveFromVersion(tdoc);
// now we save the final document..
rolledbackDoc.setOriginalDocument(tdoc);
rolledbackDoc.setAuthorReference(context.getUserReference());
rolledbackDoc.setRCSVersion(tdoc.getRCSVersion());
rolledbackDoc.setVersion(tdoc.getVersion());
rolledbackDoc.setContentDirty(true);
ObservationManager om = getObservationManager();
if (om != null) {
// Notify listeners about the document that is going to be rolled back.
// Note that for the moment the event being send is a bridge event, as we are still passing around
// an XWikiDocument as source and an XWikiContext as data.
om.notify(new DocumentRollingBackEvent(rolledbackDoc.getDocumentReference(), rev), rolledbackDoc, context);
}
saveDocument(rolledbackDoc, localizePlainOrKey("core.comment.rollback", rev), context);
// Since the the store resets the original document, we need to temporarily put it back to send notifications.
XWikiDocument newOriginalDocument = rolledbackDoc.getOriginalDocument();
rolledbackDoc.setOriginalDocument(tdoc);
try {
if (om != null) {
// Notify listeners about the document that was rolled back.
// Note that for the moment the event being send is a bridge event, as we are still passing around an
// XWikiDocument as source and an XWikiContext as data.
om.notify(new DocumentRolledBackEvent(rolledbackDoc.getDocumentReference(), rev), rolledbackDoc, context);
}
} finally {
rolledbackDoc.setOriginalDocument(newOriginalDocument);
}
return rolledbackDoc;
}
Aggregations