r7117 - in dumbhippo/trunk: openfire/src/plugins/hippo/src/java/com/dumbhippo/jive/rooms server/src/com/dumbhippo/persistence server/src/com/dumbhippo/server server/src/com/dumbhippo/server/dm server/src/com/dumbhippo/server/impl server/src/com/dumbhippo/server/views



Author: otaylor
Date: 2007-12-21 13:31:51 -0600 (Fri, 21 Dec 2007)
New Revision: 7117

Added:
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockMessageDMO.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageDMO.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageKey.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageType.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/PostMessageDMO.java
Modified:
   dumbhippo/trunk/openfire/src/plugins/hippo/src/java/com/dumbhippo/jive/rooms/Room.java
   dumbhippo/trunk/server/src/com/dumbhippo/persistence/ChatMessage.java
   dumbhippo/trunk/server/src/com/dumbhippo/persistence/EmbeddedMessage.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/ChatSystem.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockDMO.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/GroupDMO.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/dm/UserDMO.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/impl/ChatSystemBean.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/views/SystemViewpoint.java
   dumbhippo/trunk/server/src/com/dumbhippo/server/views/Viewpoint.java
Log:
Room.java: Add a session when adding post messages (notification still to-be-done)

ChatMessage EmbeddedMessage: add getTimestampAsLong()

ChatSystem ChatSystemBean: Add feed-friedlygetMessage() variant 

ChatMessage ChatMessageKey ChatMessage BlockMessage PostMessage: Start of chat
  messages in the data model.

BlockDMO: Add block.chatMessages, block.chatMessageCount

UserDMO: Remove a left-over debug message

Viewpoint SystemViewpoint: Add canSeeChatMessage()

GroupDMO: Some initial filling in of the previously empty stub

Modified: dumbhippo/trunk/openfire/src/plugins/hippo/src/java/com/dumbhippo/jive/rooms/Room.java
===================================================================
--- dumbhippo/trunk/openfire/src/plugins/hippo/src/java/com/dumbhippo/jive/rooms/Room.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/openfire/src/plugins/hippo/src/java/com/dumbhippo/jive/rooms/Room.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -674,6 +674,8 @@
 				IdentitySpider spider = EJBUtil.defaultLookup(IdentitySpider.class);
 				UserViewpoint viewpoint = new UserViewpoint(spider.lookupUser(userId), Site.XMPP);
 				
+				DataService.getModel().initializeReadWriteSession(viewpoint);
+				
 				chatSystem.addChatRoomMessage(roomGuid, kind, viewpoint, packet.getBody(), sentiment, new Date());
 			}
 		});

Modified: dumbhippo/trunk/server/src/com/dumbhippo/persistence/ChatMessage.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/persistence/ChatMessage.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/persistence/ChatMessage.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -24,4 +24,7 @@
 	
 	@Transient
 	public long getId();
+
+	@Transient
+	public long getTimestampAsLong();
 }
\ No newline at end of file

Modified: dumbhippo/trunk/server/src/com/dumbhippo/persistence/EmbeddedMessage.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/persistence/EmbeddedMessage.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/persistence/EmbeddedMessage.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -6,6 +6,7 @@
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
 
 /**
  * A chat message, we have subclasses that put the chat in a context
@@ -60,6 +61,11 @@
 	public Date getTimestamp() {
 		return timestamp >= 0 ? new Date(timestamp) : null;
 	}
+	
+	@Transient
+	public long getTimestampAsLong() {
+		return timestamp;
+	}
 
 	public void setTimestamp(Date timestamp) {
 		this.timestamp = timestamp != null ? timestamp.getTime() : -1;

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/ChatSystem.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/ChatSystem.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/ChatSystem.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -28,8 +28,12 @@
 	
 	public List<? extends ChatMessage> getNewestMessages(Block block, int maxResults);
 	
+	public List<? extends ChatMessage> getMessages(Block block, int start, int max, long minTimestamp);
+
 	public List<? extends ChatMessage> getNewestTrackMessages(TrackHistory trackHistory, int maxResults);
 
+	public List<? extends ChatMessage> getTrackMessages(TrackHistory trackHistory, int start, int max, long minTimestamp);
+
 	/**
 	 * Get the total count of messages that were sent to the chatroom about this
 	 * block.

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -1,10 +1,16 @@
 package com.dumbhippo.server.dm;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import javax.ejb.EJB;
 
 import org.slf4j.Logger;
 
 import com.dumbhippo.GlobalSetup;
+import com.dumbhippo.dm.DMFeed;
+import com.dumbhippo.dm.DMFeedItem;
 import com.dumbhippo.dm.DMObject;
 import com.dumbhippo.dm.DMSession;
 import com.dumbhippo.dm.annotations.DMFilter;
@@ -17,14 +23,21 @@
 import com.dumbhippo.dm.store.StoreKey;
 import com.dumbhippo.identity20.Guid;
 import com.dumbhippo.persistence.BlockType;
+import com.dumbhippo.persistence.ChatMessage;
 import com.dumbhippo.persistence.StackReason;
+import com.dumbhippo.persistence.User;
 import com.dumbhippo.persistence.UserBlockData;
 import com.dumbhippo.persistence.BlockType.BlockVisibility;
+import com.dumbhippo.server.ChatSystem;
 import com.dumbhippo.server.NotFoundException;
 import com.dumbhippo.server.Stacker;
 import com.dumbhippo.server.blocks.BlockView;
+import com.dumbhippo.server.blocks.EntitySourceBlockView;
+import com.dumbhippo.server.blocks.MusicPersonBlockView;
 import com.dumbhippo.server.blocks.TitleBlockView;
 import com.dumbhippo.server.blocks.TitleDescriptionBlockView;
+import com.dumbhippo.server.views.EntityView;
+import com.dumbhippo.server.views.PersonView;
 import com.dumbhippo.server.views.SystemViewpoint;
 import com.dumbhippo.server.views.UserViewpoint;
 import com.dumbhippo.server.views.Viewpoint;
@@ -49,6 +62,9 @@
 	@EJB
 	Stacker stacker;
 	
+	@EJB
+	ChatSystem chatSystem;
+
 	protected BlockDMO(BlockDMOKey key) {
 		super(key);
 	}
@@ -156,6 +172,57 @@
 		return blockView.getBlockType().getBlockVisibility() == BlockVisibility.PUBLIC;
 	}
 	
+	@DMProperty(defaultInclude=true, defaultChildren="+")
+	public UserDMO getSourceUser() {
+		if (blockView instanceof EntitySourceBlockView) {
+			/* User sources might be returned even for EntitySourceBlockView's that aren't
+			 * PersonSourceView; for example, PostBlockView, when posted by a user, instead
+			 * of a feed. 
+			 */
+			EntityView entityView = ((EntitySourceBlockView)blockView).getEntitySource();
+			if (entityView instanceof PersonView) {
+				User user = ((PersonView)entityView).getUser();
+				if (user != null)
+					return session.findUnchecked(UserDMO.class, user.getGuid());
+			}
+		}
+		
+		return null;
+	}
+
+	
+	@DMProperty(defaultInclude=true, defaultChildren="+", defaultMaxFetch=5)
+	public DMFeed<ChatMessageDMO> getChatMessages() {
+		return new MessagesFeed();
+	}
+	
+	private class MessagesFeed implements DMFeed<ChatMessageDMO> {
+		public Iterator<DMFeedItem<ChatMessageDMO>> iterator(int start, int max, long minTimestamp) {
+			List<? extends ChatMessage> messages;
+			
+			if (blockView instanceof MusicPersonBlockView)
+				messages = chatSystem.getTrackMessages(((MusicPersonBlockView)blockView).getTrack().getTrackHistory(), start, max, minTimestamp);
+			else
+				messages = chatSystem.getMessages(blockView.getBlock(), start, max, minTimestamp);
+			
+			List<DMFeedItem<ChatMessageDMO>> items = new ArrayList<DMFeedItem<ChatMessageDMO>>(); 
+			for (ChatMessage message : messages) {
+				ChatMessageDMO messageDMO = session.findUnchecked(ChatMessageDMO.class, new ChatMessageKey(message));
+				items.add(new DMFeedItem<ChatMessageDMO>(messageDMO, message.getTimestampAsLong()));
+			}
+			
+			return items.iterator();
+		}
+	}
+
+	@DMProperty(defaultInclude=true)
+	public int getChatMessageCount() {
+		if (blockView instanceof MusicPersonBlockView)
+			return chatSystem.getTrackMessageCount(((MusicPersonBlockView)blockView).getTrack().getTrackHistory());
+		else
+			return chatSystem.getMessageCount(blockView.getBlock());
+	}
+	
 	//////////////////////////////////////////////////////////////////////
 	
 	@DMInit(group=USER_BLOCK_DATA_GROUP, initMain=false) 

Added: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockMessageDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockMessageDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/BlockMessageDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -0,0 +1,26 @@
+package com.dumbhippo.server.dm;
+
+import com.dumbhippo.dm.annotations.DMO;
+import com.dumbhippo.dm.store.StoreKey;
+import com.dumbhippo.persistence.BlockMessage;
+import com.dumbhippo.server.NotFoundException;
+
+ DMO(classId="http://mugshot.org/p/o/blockMessage";)
+public abstract class BlockMessageDMO extends ChatMessageDMO {
+	protected BlockMessageDMO(ChatMessageKey key) {
+		super(key);
+	}
+
+	@Override
+	protected void init() throws NotFoundException {
+		message = em.find(BlockMessage.class, getKey().getId());
+		if (message == null)
+			throw new NotFoundException("No such block message");
+	}
+	
+	@Override
+	public StoreKey<?,?> getVisibilityDelegate() {
+		BlockDMO block = session.findUnchecked(BlockDMO.class, new BlockDMOKey(((BlockMessage)message).getBlock())); 
+		return block.getStoreKey();
+	}
+}

Added: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -0,0 +1,71 @@
+package com.dumbhippo.server.dm;
+
+import javax.persistence.EntityManager;
+
+import com.dumbhippo.dm.DMObject;
+import com.dumbhippo.dm.DMSession;
+import com.dumbhippo.dm.annotations.DMFilter;
+import com.dumbhippo.dm.annotations.DMO;
+import com.dumbhippo.dm.annotations.DMProperty;
+import com.dumbhippo.dm.annotations.Inject;
+import com.dumbhippo.dm.annotations.MetaConstruct;
+import com.dumbhippo.dm.store.StoreKey;
+import com.dumbhippo.persistence.ChatMessage;
+import com.dumbhippo.persistence.Sentiment;
+
+ DMO(classId="http://mugshot.org/p/o/chatMessage";, resourceBase="/o/chatMessage")
+ DMFilter("viewer.canSeeChatMessage(this)")
+public abstract class ChatMessageDMO extends DMObject<ChatMessageKey> {
+	protected ChatMessage message;
+	
+	@Inject
+	protected DMSession session;
+	
+	@Inject
+	protected EntityManager em;
+
+	protected ChatMessageDMO(ChatMessageKey key) {
+		super(key);
+	}
+
+	@MetaConstruct
+	public static Class<? extends ChatMessageDMO> getDMOClass(ChatMessageKey key) {
+		switch (key.getType()) {
+		case BLOCK:
+			return BlockMessageDMO.class;
+		case POST:
+			return PostMessageDMO.class;
+		case GROUP:
+		case TRACK:
+			return null;
+		}
+		
+		return null;
+	}
+
+	@DMProperty(defaultInclude=true)
+	public UserDMO getSender() {
+		return session.findUnchecked(UserDMO.class, message.getFromUser().getGuid());
+	}
+	
+	@DMProperty(defaultInclude=true)
+	public String getText(){
+		return message.getMessageText();
+	}
+	
+	@DMProperty(defaultInclude=true)
+	public long getTime() {
+		return message.getTimestamp().getTime();
+	}
+	
+	@DMProperty(defaultInclude=true)
+	public String getSentiment() {
+		if (message.getSentiment() == Sentiment.INDIFFERENT)
+			return null;
+		else
+			return message.getSentiment().name();
+	}
+	
+	@DMProperty 
+	public abstract StoreKey<?,?> getVisibilityDelegate();
+}

Added: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageKey.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageKey.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageKey.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -0,0 +1,88 @@
+package com.dumbhippo.server.dm;
+
+import com.dumbhippo.dm.BadIdException;
+import com.dumbhippo.dm.DMKey;
+import com.dumbhippo.persistence.BlockMessage;
+import com.dumbhippo.persistence.ChatMessage;
+import com.dumbhippo.persistence.GroupMessage;
+import com.dumbhippo.persistence.PostMessage;
+import com.dumbhippo.persistence.TrackMessage;
+
+public class ChatMessageKey implements DMKey {
+	private static final long serialVersionUID = 4974136343974507951L;
+	
+	private long id;
+	private ChatMessageType type;
+	
+	public ChatMessageKey(String keyString) throws BadIdException {
+		int dot = keyString.indexOf(".");
+		if (dot < 0)
+			throw new BadIdException("Invalid format for chat message key");
+
+		try {
+			id = Long.parseLong(keyString.substring(0, dot));
+		} catch (NumberFormatException e) {
+			throw new BadIdException("Invalid message id in chat message key");
+		}
+		
+		try {
+			type = ChatMessageType.valueOf(keyString.substring(dot + 1));
+		} catch (IllegalArgumentException e) {
+			throw new BadIdException("Bad chat message type in ID", e);
+		}
+	}
+	
+	public ChatMessageKey(long id, ChatMessageType type) {
+		this.id = id;
+		this.type = type;
+	}
+	
+	public ChatMessageKey(ChatMessage message) {
+		this(message.getId(), getTypeForMessage(message));
+	}
+	
+	private static ChatMessageType getTypeForMessage(ChatMessage message) {
+		if (message instanceof BlockMessage)
+			return ChatMessageType.BLOCK;
+		else if (message instanceof GroupMessage)
+			return ChatMessageType.GROUP;
+		else if (message instanceof PostMessage)
+			return ChatMessageType.POST;
+		else if (message instanceof TrackMessage)
+			return ChatMessageType.TRACK;
+		else
+			throw new RuntimeException("Unexpected message type: " + message.getClass().getName());
+	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	public ChatMessageType getType() {
+		return type;
+	}
+		
+	@Override
+	public int hashCode() {
+		return (int)(id * 23 + type.ordinal() * 29);
+	}
+	
+	@Override
+	public boolean equals(Object o) {
+		if (!(o instanceof ChatMessageKey))
+			return false;
+		
+		ChatMessageKey other = (ChatMessageKey)o;
+		return id == other.id && type == other.type;
+	}
+	
+	@Override
+	public ChatMessageKey clone() {
+		return this;
+	}
+	
+	@Override
+	public String toString() {
+		return id + "." + type.name();
+	}
+}

Added: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageType.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageType.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/ChatMessageType.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -0,0 +1,8 @@
+package com.dumbhippo.server.dm;
+
+public enum ChatMessageType {
+	BLOCK,
+	GROUP,
+	POST,
+	TRACK
+}

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -93,6 +93,10 @@
 		model.addDMClass(PicasaPersonBlockDMO.class);
 		model.addDMClass(PostBlockDMO.class);
 		
+		model.addDMClass(ChatMessageDMO.class);
+		model.addDMClass(BlockMessageDMO.class);
+		model.addDMClass(PostMessageDMO.class);
+
 		model.addDMClass(ContactDMO.class);
 		model.addDMClass(DesktopSettingDMO.class);
 		model.addDMClass(ExternalAccountDMO.class);

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/GroupDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/GroupDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/GroupDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -1,5 +1,48 @@
 package com.dumbhippo.server.dm;
 
-public class GroupDMO {
+import javax.persistence.EntityManager;
 
+import com.dumbhippo.dm.DMObject;
+import com.dumbhippo.dm.annotations.DMFilter;
+import com.dumbhippo.dm.annotations.DMO;
+import com.dumbhippo.dm.annotations.DMProperty;
+import com.dumbhippo.dm.annotations.Inject;
+import com.dumbhippo.dm.annotations.PropertyType;
+import com.dumbhippo.identity20.Guid;
+import com.dumbhippo.persistence.Group;
+import com.dumbhippo.server.NotFoundException;
+
+ DMO(classId="http://mugshot.org/p/o/group";, resourceBase="/o/group")
+ DMFilter("viewer.canSeeGroup(this)")
+public abstract class GroupDMO extends DMObject<Guid> {
+	@Inject
+	private EntityManager em;
+	
+	private Group group;
+	
+	protected GroupDMO(Guid key) {
+		super(key);
+	}
+
+	@Override
+	protected void init() throws NotFoundException {
+		group = em.find(Group.class, getKey().toString());
+		if (group == null)
+			throw new NotFoundException("No such group");
+	}
+	
+	@DMProperty(defaultInclude=true)
+	public String getName() {
+		return group.getName();
+	}
+	
+	@DMProperty(defaultInclude=true, type=PropertyType.URL)
+	public String getPhotoUrl() {
+		return group.getPhotoUrl();
+	}
+	
+	@DMProperty(defaultInclude=true, type=PropertyType.URL)
+	public String getHomeUrl() {
+		return "/group?who=" + group.getId();
+	}
 }

Added: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/PostMessageDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/PostMessageDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/PostMessageDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -0,0 +1,26 @@
+package com.dumbhippo.server.dm;
+
+import com.dumbhippo.dm.annotations.DMO;
+import com.dumbhippo.dm.store.StoreKey;
+import com.dumbhippo.persistence.PostMessage;
+import com.dumbhippo.server.NotFoundException;
+
+ DMO(classId="http://mugshot.org/p/o/postMessage";)
+public abstract class PostMessageDMO extends ChatMessageDMO {
+	protected PostMessageDMO(ChatMessageKey key) {
+		super(key);
+	}
+
+	@Override
+	protected void init() throws NotFoundException {
+		message = em.find(PostMessage.class, getKey().getId());
+		if (message == null)
+			throw new NotFoundException("No such post message");
+	}
+	
+	@Override
+	public StoreKey<?,?> getVisibilityDelegate() {
+		PostDMO post = session.findUnchecked(PostDMO.class, ((PostMessage)message).getPost().getGuid()); 
+		return post.getStoreKey();
+	}
+}

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/UserDMO.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/UserDMO.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/UserDMO.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -471,8 +471,6 @@
 			for (UserBlockData ubd : blocks) {
 				Class<? extends BlockDMO> dmoClass = BlockDMO.getDMOClass(ubd.getBlock().getBlockType());
 				if (dmoClass != null) {
-					logger.debug("dmoClass for {} is {}", ubd.getBlock().getBlockType(), dmoClass.getName());
-					
 					BlockDMO blockDMO = session.findUnchecked(dmoClass, new BlockDMOKey(ubd.getBlock()));
 					items.add(new DMFeedItem<BlockDMO>(blockDMO, ubd.getStackTimestampAsLong()));
 				}

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/impl/ChatSystemBean.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/impl/ChatSystemBean.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/impl/ChatSystemBean.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -93,13 +93,6 @@
 	@IgnoreDependency
 	private Stacker stacker;
 	
-	// We order and select on pm.id, though in rare cases the order by pm.id and by pm.timestamp
-	// might be different if two messages arrive almost at once. In this case, the timestamps will
-	// likely be within a second of each other and its much cheaper this way.
-	private static final String BLOCK_MESSAGE_QUERY = "SELECT pm from BlockMessage pm WHERE pm.block = :block";
-	private static final String BLOCK_MESSAGE_SELECT = " AND pm.id >= :lastSeenSerial ";
-	private static final String BLOCK_MESSAGE_ORDER = " ORDER BY pm.id";
-	
 	public List<? extends ChatMessage> getMessages(Block block, long lastSeenSerial) {
 		switch (block.getBlockType()) {
 		case GROUP_CHAT:
@@ -126,22 +119,44 @@
 		switch (block.getBlockType()) {
 		case GROUP_CHAT:
 			Group group = em.find(Group.class, block.getData1AsGuid().toString());
-			return getNewestGroupMessages(group, maxResults);
+			return getGroupMessages(group, 0, maxResults, -1);
 		case MUSIC_CHAT:
 			TrackHistory trackHistory = em.find(TrackHistory.class, block.getData2AsGuid().toString());
-			return getNewestTrackMessages(trackHistory, maxResults);
+			return getTrackMessages(trackHistory, 0, maxResults, -1);
 		case POST:
 			Post post = em.find(Post.class, block.getData1AsGuid().toString());
-			return getNewestPostMessages(post, maxResults);
+			return getPostMessages(post, 0, maxResults, -1);
 		case MUSIC_PERSON:
 			throw new RuntimeException("Use getNewestTrackMessages() instead"); // for efficiency 
 		case GROUP_MEMBER:
 			return Collections.emptyList();
 		default:
-			return getNewestBlockMessages(block, maxResults);
+			return getBlockMessages(block, 0, maxResults, -1);
 		}
 	}
 		
+	public List<? extends ChatMessage> getMessages(Block block, int start, int max, long minTimestamp) {
+		switch (block.getBlockType()) {
+		case GROUP_CHAT:
+			Group group = em.find(Group.class, block.getData1AsGuid().toString());
+			return getGroupMessages(group, start, max, minTimestamp);
+		case MUSIC_CHAT:
+			TrackHistory trackHistory = em.find(TrackHistory.class, block.getData2AsGuid().toString());
+			return getTrackMessages(trackHistory, start, max, minTimestamp);
+		case POST:
+			Post post = em.find(Post.class, block.getData1AsGuid().toString());
+			return getPostMessages(post, start, max, minTimestamp);
+		case MUSIC_PERSON:
+			// If the caller already has a BlockView and hence the latest TrackHistory,
+			// we don't want to look that up again here
+			throw new RuntimeException("Use getTrackMessages() instead"); 
+		case GROUP_MEMBER:
+			return Collections.emptyList();
+		default:
+			return getBlockMessages(block, start, max, minTimestamp);
+		}
+	}
+
 	public int getMessageCount(Block block) {
 		switch (block.getBlockType()) {
 		case GROUP_CHAT:
@@ -162,6 +177,13 @@
 		}
 	}
 	
+	// We order and select on bm.id, though in rare cases the order by bm.id and by pm.timestamp
+	// might be different if two messages arrive almost at once. In this case, the timestamps will
+	// likely be within a second of each other and its much cheaper this way.
+	private static final String BLOCK_MESSAGE_QUERY = "SELECT bm from BlockMessage bm WHERE bm.block = :block";
+	private static final String BLOCK_MESSAGE_SELECT = " AND bm.id >= :lastSeenSerial ";
+	private static final String BLOCK_MESSAGE_ORDER = " ORDER BY bm.id";
+	
 	private List<BlockMessage> getBlockMessages(Block block, long lastSeenSerial) {
 		List<?> messages = em.createQuery(BLOCK_MESSAGE_QUERY + BLOCK_MESSAGE_SELECT + BLOCK_MESSAGE_ORDER)
 			.setParameter("block", block)
@@ -171,13 +193,22 @@
 		return TypeUtils.castList(BlockMessage.class, messages);
 	}
 	
-	private List<BlockMessage> getNewestBlockMessages(Block block, int maxResults) {
-		List<?> messages = em.createQuery("SELECT bm from BlockMessage bm WHERE bm.block = :block ORDER BY bm.timestamp DESC")
-			.setParameter("block", block)
-			.setMaxResults(maxResults)
-			.getResultList();
+	private List<BlockMessage> getBlockMessages(Block block, int start, int max, long minTimestamp) {
+		Query q;
 		
-		return TypeUtils.castList(BlockMessage.class, messages);		
+		if (minTimestamp >=0) {
+			q = em.createQuery("SELECT bm from BlockMessage bm WHERE bm.block = :block AND bm.timestamp >= :minTimestamp ORDER BY bm.timestamp DESC");
+			q.setParameter("minTimestamp", new Date(minTimestamp));
+		} else {
+			q = em.createQuery("SELECT bm from BlockMessage bm WHERE bm.block = :block ORDER BY bm.timestamp DESC");
+		}
+		
+		q.setParameter("block", block);
+		q.setFirstResult(start);
+		if (max >= 0)
+			q.setMaxResults(max);
+		
+		return TypeUtils.castList(BlockMessage.class, q.getResultList());
 	}
 	
 	private int getBlockMessageCount(Block block) {
@@ -210,13 +241,22 @@
 		return TypeUtils.castList(PostMessage.class, messages);
 	}
 	
-	private List<PostMessage> getNewestPostMessages(Post post, int maxResults) {
-		List<?> messages = em.createQuery("SELECT pm from PostMessage pm WHERE pm.post = :post ORDER BY pm.timestamp DESC")
-		.setParameter("post", post)
-		.setMaxResults(maxResults)
-		.getResultList();
+	private List<PostMessage> getPostMessages(Post post, int start, int max, long minTimestamp) {
+		Query q;
 		
-		return TypeUtils.castList(PostMessage.class, messages);		
+		if (minTimestamp >=0) {
+			q = em.createQuery("SELECT pm from PostMessage pm WHERE pm.post = :post AND pm.timestamp >= :minTimestamp ORDER BY pm.timestamp DESC");
+			q.setParameter("minTimestamp", new Date(minTimestamp));
+		} else {
+			q = em.createQuery("SELECT pm from PostMessage pm WHERE pm.post = :post ORDER BY pm.timestamp DESC");
+		}
+		
+		q.setParameter("post", post);
+		q.setFirstResult(start);
+		if (max >= 0)
+			q.setMaxResults(max);
+		
+		return TypeUtils.castList(PostMessage.class, q.getResultList());
 	}
 	
 	private int getPostMessageCount(Post post) {
@@ -249,13 +289,22 @@
 		return TypeUtils.castList(GroupMessage.class, messages);
 	}
 	
-	private List<GroupMessage> getNewestGroupMessages(Group group, int maxResults) {
-		List<?> messages =  em.createQuery(GROUP_MESSAGE_QUERY + GROUP_MESSAGE_ORDER + " DESC")
-		.setParameter("group", group)
-		.setMaxResults(maxResults)
-		.getResultList();
+	private List<GroupMessage> getGroupMessages(Group group, int start, int max, long minTimestamp) {
+		Query q;
 		
-		return TypeUtils.castList(GroupMessage.class, messages);		
+		if (minTimestamp >=0) {
+			q = em.createQuery("SELECT gm from GroupMessage gm WHERE gm.group = :group AND gm.timestamp >= :minTimestamp ORDER BY gm.timestamp DESC");
+			q.setParameter("minTimestamp", new Date(minTimestamp));
+		} else {
+			q = em.createQuery("SELECT gm from GroupMessage gm WHERE gm.group = :group ORDER BY gm.timestamp DESC");
+		}
+		
+		q.setParameter("group", group);
+		q.setFirstResult(start);
+		if (max >= 0)
+			q.setMaxResults(max);
+		
+		return TypeUtils.castList(GroupMessage.class, q.getResultList());
 	}
 	
 	private int getGroupMessageCount(Group group) {
@@ -272,14 +321,27 @@
 		return groupMessage;
 	}
 
-	public List<TrackMessage> getNewestTrackMessages(TrackHistory trackHistory, int maxResults) {
-		Query q = em.createQuery("SELECT tm from TrackMessage tm WHERE tm.trackHistory = :trackHistory ORDER by tm.timestamp DESC");
+	public List<TrackMessage> getTrackMessages(TrackHistory trackHistory, int start, int max, long minTimestamp) {
+		Query q;
+		
+		if (minTimestamp >=0) {
+			q = em.createQuery("SELECT tm from TrackMessage tm WHERE tm.trackHistory = :trackHistory AND tm.timestamp > :minTimestamp ORDER by tm.timestamp DESC");
+			q.setParameter("minTimestamp", new Date(minTimestamp));
+		} else {
+			q = em.createQuery("SELECT tm from TrackMessage tm WHERE tm.trackHistory = :trackHistory ORDER by tm.timestamp DESC");
+		}
+		
 		q.setParameter("trackHistory", trackHistory);
-		if (maxResults >= 0)
-			q.setMaxResults(maxResults);
+		q.setFirstResult(start);
+		if (max >= 0)
+			q.setMaxResults(max);
 		
 		return TypeUtils.castList(TrackMessage.class, q.getResultList());
 	}
+	
+	public List<TrackMessage> getNewestTrackMessages(TrackHistory trackHistory, int maxResults) {
+		return getTrackMessages(trackHistory, 0, maxResults, -1);
+	}
 
 	private List<TrackMessage> getTrackMessages(TrackHistory trackHistory, long lastSeenSerial) {
 		Query q = em.createQuery("SELECT tm from TrackMessage tm WHERE tm.trackHistory = :trackHistory AND tm.id >= :lastSeenSerial ORDER by tm.id");
@@ -311,14 +373,6 @@
 		return viewedMsgs;
 	}
 
-	private User getUserFromGuid(Guid guid) {
-		try {
-			return identitySpider.lookupGuid(User.class, guid);
-		} catch (NotFoundException e) {
-			throw new RuntimeException("User does not exist: " + guid, e);
-		}
-	}
-	
 	private Post getPostForRoom(Guid roomGuid) throws NotFoundException {
 		return postingBoard.loadRawPost(SystemViewpoint.getInstance(), roomGuid);
 	}
@@ -575,5 +629,5 @@
 		default:
 			throw new RuntimeException("Unknown chat room type " + kind);
 		}
-	}	
+	}
 }

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/views/SystemViewpoint.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/views/SystemViewpoint.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/views/SystemViewpoint.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -5,6 +5,7 @@
 import com.dumbhippo.identity20.Guid;
 import com.dumbhippo.persistence.User;
 import com.dumbhippo.server.dm.BlockDMOKey;
+import com.dumbhippo.server.dm.ChatMessageKey;
 
 /**
  * SystemViewpoint represents the systems view of the database.
@@ -79,4 +80,10 @@
 	public Site getSite() {
 		return Site.NONE;
 	}
+
+	// Override as an optimization
+	@Override
+	public boolean canSeeChatMessage(ChatMessageKey chatMessageKey) {
+		return true;
+	}
 }

Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/views/Viewpoint.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/views/Viewpoint.java	2007-12-21 19:27:18 UTC (rev 7116)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/views/Viewpoint.java	2007-12-21 19:31:51 UTC (rev 7117)
@@ -1,10 +1,16 @@
 package com.dumbhippo.server.views;
 
 import com.dumbhippo.Site;
+import com.dumbhippo.dm.DMSession;
 import com.dumbhippo.dm.DMViewpoint;
+import com.dumbhippo.dm.store.StoreKey;
 import com.dumbhippo.identity20.Guid;
 import com.dumbhippo.persistence.User;
+import com.dumbhippo.server.NotFoundException;
 import com.dumbhippo.server.dm.BlockDMOKey;
+import com.dumbhippo.server.dm.ChatMessageDMO;
+import com.dumbhippo.server.dm.ChatMessageKey;
+import com.dumbhippo.server.dm.DataService;
 
 /**
  * The Viewpoint class represents the concept of "current user". 
@@ -61,4 +67,16 @@
 	public AnonymousViewpoint anonymize() {
 		return AnonymousViewpoint.getInstance(getSite());
 	}
+	
+	public boolean canSeeChatMessage(ChatMessageKey chatMessageKey) {
+		DMSession session = DataService.getModel().currentSession();
+
+		StoreKey<?, ?> delegateKey;
+		try {
+			delegateKey = (StoreKey<?,?>)session.getRawProperty(ChatMessageDMO.class, chatMessageKey, "visibilityDelegate");
+			return delegateKey.isVisible(this);
+		} catch (NotFoundException e) {
+			return false;
+		}
+	}
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]