From 93b8d7b0c52fed9b6e5792da123bbdb886df44ca Mon Sep 17 00:00:00 2001
From: gnaegi <none@none>
Date: Tue, 25 Sep 2012 14:05:18 +0200
Subject: [PATCH] OO-363 fix some bugs in blog to make it more robust and not
 loose items

---
 .../org/olat/modules/webFeed/models/Feed.java |  2 +
 .../org/olat/modules/webFeed/models/Item.java |  4 ++
 .../webFeed/ui/FeedMainController.java        |  4 ++
 .../modules/webFeed/ui/ItemsController.java   | 59 ++++++++++++++-----
 4 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/olat/modules/webFeed/models/Feed.java b/src/main/java/org/olat/modules/webFeed/models/Feed.java
index 522f9a2316c..770e6bd011b 100644
--- a/src/main/java/org/olat/modules/webFeed/models/Feed.java
+++ b/src/main/java/org/olat/modules/webFeed/models/Feed.java
@@ -306,6 +306,8 @@ public class Feed implements OLATResourceable, Serializable {
 	 */
 	public boolean remove(Item item) {
 		itemIds.remove(item.getGuid());
+		// Remove below works also when object identity is not the same as
+		// item.equals has been overwritten to match on the GUID
 		return items.remove(item);
 	}
 
diff --git a/src/main/java/org/olat/modules/webFeed/models/Item.java b/src/main/java/org/olat/modules/webFeed/models/Item.java
index 54b3e62a1e8..674d3e87914 100644
--- a/src/main/java/org/olat/modules/webFeed/models/Item.java
+++ b/src/main/java/org/olat/modules/webFeed/models/Item.java
@@ -344,6 +344,10 @@ public class Item implements Serializable, Dated {
 		return guid == null ? 39745 : guid.hashCode();
 	}
 	
+	/**
+	 * Overwrite equals method so that different object in the vm that actually
+	 * represent the same item are recognized as such. Eg in the remove method of the feed
+	 */
 	public boolean equals(Object obj) {
 		if(this == obj) {
 			return true;
diff --git a/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java b/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
index 6f166230a51..f83d9c69984 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
+++ b/src/main/java/org/olat/modules/webFeed/ui/FeedMainController.java
@@ -169,6 +169,10 @@ public class FeedMainController extends BasicController implements Activateable2
 	 */
 	@Override
 	protected void event(UserRequest ureq, Component source, Event event) {
+		// feed for this event and make sure the updated feed object is in the view
+		feed = feedManager.getFeed(feed);
+		vcInfo.contextPut("feed", feed);
+		
 		if (source == editFeedButton) {
 			lock = feedManager.acquireLock(feed, ureq.getIdentity());
 			if (lock.isSuccess()) {
diff --git a/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java b/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
index 20b37390a80..91e31a0e901 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
+++ b/src/main/java/org/olat/modules/webFeed/ui/ItemsController.java
@@ -389,7 +389,10 @@ public class ItemsController extends BasicController implements Activateable2 {
 	@Override
 	protected void event(UserRequest ureq, Component source, Event event) {
 		FeedManager feedManager = FeedManager.getInstance();
+		// feed for this event and make sure the updated feed object is in the view
 		Feed feed = feedManager.getFeed(feedResource);
+		vcItems.contextPut("feed", feed);
+		
 		if (source == addItemButton) {
 			currentItem = new Item();
 			currentItem.setDraft(true);
@@ -403,14 +406,20 @@ public class ItemsController extends BasicController implements Activateable2 {
 
 		} else if (editButtons != null && editButtons.contains(source)) {
 			currentItem = (Item) ((Link) source).getUserObject();
-			lock = feedManager.acquireLock(feed, currentItem, getIdentity());
-			if (lock.isSuccess()) {
-
-				itemFormCtr = uiFactory.createItemFormController(ureq, getWindowControl(), currentItem, feed);
-				activateModalDialog(itemFormCtr);
+			// check if still available, maybe deleted by other user in the meantime
+			if (feed.getItems().contains(currentItem)) {
+				lock = feedManager.acquireLock(feed, currentItem, getIdentity());
+				if (lock.isSuccess()) {
+					
+					itemFormCtr = uiFactory.createItemFormController(ureq, getWindowControl(), currentItem, feed);
+					activateModalDialog(itemFormCtr);
+				} else {
+					showInfo("feed.item.is.being.edited.by", lock.getOwner().getName());
+				}				
 			} else {
-				showInfo("feed.item.is.being.edited.by", lock.getOwner().getName());
+				showInfo("feed.item.is.being.edited.by", "unknown");
 			}
+			
 		} else if (deleteButtons != null && deleteButtons.contains(source)) {
 			Item item = (Item) ((Link) source).getUserObject();
 			confirmDialogCtr = activateYesNoDialog(ureq, null, translate("feed.item.confirm.delete"), confirmDialogCtr);
@@ -421,7 +430,16 @@ public class ItemsController extends BasicController implements Activateable2 {
 			displayItemController(ureq, item);
 
 		} else if (source == makeInternalButton) {
-			feedManager.updateFeedMode(Boolean.FALSE, feed);
+			if (feed.isUndefined()) {
+				feedManager.updateFeedMode(Boolean.FALSE, feed);				
+			} else if (feed.isExternal()) {
+				// Very special case: another user concurrently changed feed to external. Do nothing
+				vcItems.setDirty(true);
+				return;
+			}
+			// else nothing to do, already set to internal by a concurrent user
+			
+			// Add temporary item and open edit dialog
 			addItemButton = LinkFactory.createButton("feed.add.item", vcItems, this);
 			addItemButton.setElementCssClass("o_sel_feed_item_new");
 			currentItem = new Item();
@@ -435,15 +453,19 @@ public class ItemsController extends BasicController implements Activateable2 {
 			activateModalDialog(itemFormCtr);
 			// do logging
 			ThreadLocalUserActivityLogger.log(FeedLoggingAction.FEED_EDIT, getClass(), LoggingResourceable.wrap(feed));
+			
 
 		} else if (source == makeExternalButton) {
-			feedManager.updateFeedMode(Boolean.TRUE, feed);
-			vcItems.setDirty(true);
-			// Ask listening FeedMainController to open and handle a new external
-			// feed dialog.
-			fireEvent(ureq, HANDLE_NEW_EXTERNAL_FEED_DIALOG_EVENT);
-			// do logging
-			ThreadLocalUserActivityLogger.log(FeedLoggingAction.FEED_EDIT, getClass(), LoggingResourceable.wrap(feed));
+			if (feed.isUndefined()) {
+				feedManager.updateFeedMode(Boolean.TRUE, feed);
+				vcItems.setDirty(true);
+				// Ask listening FeedMainController to open and handle a new external
+				// feed dialog.
+				fireEvent(ureq, HANDLE_NEW_EXTERNAL_FEED_DIALOG_EVENT);
+				// do logging
+				ThreadLocalUserActivityLogger.log(FeedLoggingAction.FEED_EDIT, getClass(), LoggingResourceable.wrap(feed));
+			} 
+			// else nothing to do, already set to external by a concurrent user
 
 		} else if (source == olderItemsLink) {
 			helper.olderItems();
@@ -492,7 +514,11 @@ public class ItemsController extends BasicController implements Activateable2 {
 				dts.activate(ureq, dt, null);
 			}
 		}
-
+		
+		// Check if someone else added an item, reload everything
+		if (!isSameAllItems(feed.getFilteredItems(callback, ureq.getIdentity()))) {
+			resetItems(ureq, feed);
+		}
 	}
 
 	/**
@@ -501,7 +527,10 @@ public class ItemsController extends BasicController implements Activateable2 {
 	 */
 	protected void event(UserRequest ureq, Controller source, Event event) {
 		FeedManager feedManager = FeedManager.getInstance();
+		// reload feed for this event and make sure the updated feed object is in the view
 		Feed feed = feedManager.getFeed(feedResource);
+		vcItems.contextPut("feed", feed);
+
 		if (source == cmc) {
 			if (event.equals(CloseableModalController.CLOSE_MODAL_EVENT)) {
 				removeAsListenerAndDispose(cmc);
-- 
GitLab