/* * Copyright (c) 2013 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); you * may not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.google.appengine.demos.websocketchat.domain; import com.googlecode.objectify.Key; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Parent; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; import static com.googlecode.objectify.ObjectifyService.ofy; /** * An entity class which holds a list of participants for a chat room within a single server node. * * <p>The parentKey parameter should be set with the name of the chat room as the key name. This * is forced by only providing a single public constructor which has {@code String room} as the * first parameter. * </p> */ @Entity public class ChatRoomParticipants { private static final Logger LOG = Logger.getLogger(ChatRoomParticipants.class.getName()); /* parentKey has a room name as the key name. */ @Parent private Key<ChatRoomParticipants> parentKey; @Id private String serverNode; private Set<String> participants; /* Objectify needs the default constructor. */ private ChatRoomParticipants() {} /** * Returns the global list of participants of the given chat room. * * <p>This method aggregates the participants list among multiple servers and return the * global list of the given chat room.</p> * * @param room a name of the chat room. * @return the global list of participants of the given chat room. */ public static Set<String> getParticipants(String room) { List<Key<WebSocketServerNode>> serverNodeKeyList = ofy().load() .type(WebSocketServerNode.class).ancestor(WebSocketServerNode.getRootKey()).keys().list(); List<Key<ChatRoomParticipants>> chatRoomParticipantsKeys = new ArrayList<>(); Key<ChatRoomParticipants> parentKey = Key.create(ChatRoomParticipants.class, room); for (Key<WebSocketServerNode> serverNodeKey: serverNodeKeyList) { Key<ChatRoomParticipants> chatRoomParticipantsKey = Key.create(parentKey, ChatRoomParticipants.class, serverNodeKey.getName()); LOG.info("chatRoomParticipantsKey: " + chatRoomParticipantsKey); chatRoomParticipantsKeys.add(chatRoomParticipantsKey); } Collection<ChatRoomParticipants> chatRoomParticipantsCollection = ofy().transaction().load().keys(chatRoomParticipantsKeys).values(); Set<String> participantSet = new TreeSet<>(); for (ChatRoomParticipants participants: chatRoomParticipantsCollection) { LOG.info("Adding " + participants.getParticipants()); participantSet.addAll(participants.getParticipants()); } return participantSet; } /** * Creates an entity representing the list of the participants in a chat room within a single * server node. * * @param room a name of the chat room. * @param serverNode an identifier of a single server node, in the form of websocket URL, * e.x. "ws://173.255.112.201:65080/". * @param participants a set of participants in the given chat room within a single server node. */ public ChatRoomParticipants(String room, String serverNode, Set<String> participants) { this.parentKey = Key.create(ChatRoomParticipants.class, room); this.serverNode = serverNode; this.participants = new TreeSet<>(participants); } /** * Returns the list of the participants in this entity. * * @return the list of the participants in the given chat room within a single server node. */ public Set<String> getParticipants() { if (participants == null) { return new TreeSet<>(); } return new TreeSet<>(participants); } /** * Returns the objectify key object representing this entity. * * @return the objectify key object representing this entity. */ public Key<ChatRoomParticipants> getKey() { return Key.create(this.parentKey, ChatRoomParticipants.class, serverNode); } }