Generalized Data Structure Synthesis Calvin Loncaric Michael D. Ernst Emina Torlak � 1
Stateful modules are much more complicated than their specifications Specification Implementation 1992 Lines of code 1383 292 157 3668 41 42 ZTopo Sat4j Openfire Lucene ! 2
User Visibility in Openfire Alice Bob Can Alice see whether Bob is online? Yes, if: Alice “subscribed” to Bob AND Bob approved it Bob is a member of a group g that is visible to everyone Alice and Bob are in a group together Alice is in group g 1 , Bob is in group g 2 , and g 2 is a “child” of g 1 ! 3
User visibility in code boolean isRosterItem(JID user) { void groupUserAdded(Group group, …, JID addedUser) { return // Get the roster of the added user. Roster addedUserRoster = null; rosterItems.get(user.toBareJID()) != null || void addSharedUser (Group group, JID addedUser) { if (server.isLocal(addedUser)) { boolean newItem = false; addedUserRoster = rosterCache.get(addedUser.getNode()); implicitFrom.get(user.toBareJID()) != null; RosterItem item = null; } void addSharedUser (JID addedUser, Collection<Group> g try { // Get the RosterItem for the *local* user to add boolean newItem = false; // Iterate on all the affected users and update their rosters item = getRosterItem(addedUser); RosterItem item = null; for (JID userToUpdate : users) { // Do nothing if the item already includes the shared group try { if (!addedUser.equals(userToUpdate)) { if (item.getSharedGroups().contains(group)) { // Get the RosterItem for the *local* user to add // Get the roster to update return; item = getRosterItem(addedUser); Roster roster = null; } newItem = false; if (server.isLocal(userToUpdate)) { newItem = false; } catch (UserNotFoundException e) { // Check that the user exists, if not then continue with the next user } catch (UserNotFoundException e) { try { try { try { // Create a new RosterItem for this new user UserManager.getInstance().getUser(userToUpdate.getNode()); // Create a new RosterItem for this new user String nickname = UserNameManager } String nickname = UserNameManager.getUserName(addedUser); item = catch (UserNotFoundException e) { item = new RosterItem(addedUser, RosterItem.SUB_BOTH, R continue; new RosterItem(addedUser, RosterItem.SUB_BOTH, RosterItem.ASK_NONE, RosterItem.RECV_NONE, nic } RosterItem.RECV_NONE, nickname, null); // Add the new item to the list of items roster = rosterCache.get(userToUpdate.getNode()); Only correct when // Add the new item to the list of items rosterItems.put(item.getJid().toBareJID(), item); } rosterItems.put(item.getJid().toBareJID(), item); newItem = true; // Only update rosters in memory newItem = true; } catch (UserNotFoundException ex) { if (roster != null) { these maps are in the } catch (UserNotFoundException ex) { Log.error("Couldn't find a user with user roster.addSharedUser(group, addedUser); Log.error("Group (" + group.getName() + ") includes non-existent username (" + } } addedUser + } // Check if the roster is still not in memory correct state! ")"); // Update the subscription of the item **based on the item g if (addedUserRoster == null && server.isLocal(addedUser)) { } Collection<Group> userGroups = GroupManag addedUserRoster = } // Set subscription type to BOTH if the roster user belongs to a shared g rosterCache.get(addedUser.getNode()); // that is mutually visible with a shared g } // If an item already exists then take note of the old subscription status if (rosterManager.hasMutualVisibility(getUser // Update the roster of the newly added group user. RosterItem.SubType prevSubscription = null; item.setSubStatus(RosterItem.SUB_BOTH); if (addedUserRoster != null) { if (!newItem) { for (Group group : groups) { Collection<Group> groups = GroupManager.getInstance().getGroups(userToUpdate); prevSubscription = item.getSubStatus(); if (rosterManager.isGroupVisible(group, g addedUserRoster.addSharedUser(userToUpdate, groups, group); } // Add the shared group to the list of shared g } item.addSharedGroup(group); if (!server.isLocal(addedUser)) { // Update the subscription of the item **based on the item groups** } // Susbcribe to the presence of the remote user. This is only necessary for Collection<Group> userGroups = GroupManager.getInstance().getGroups(getUserJID()); } // remote users and may only work with remote users that **automatically** Collection<Group> sharedGroups = new ArrayList<>(); // Add to the item the groups of this user that g // accept presence subscription requests sharedGroups.addAll(item.getSharedGroups()); // Note: This FROM subscription is over sendSubscribeRequest(userToUpdate, addedUser, true); // Add the new group to the list of groups to check // fact there is a TO-FROM relation betw } sharedGroups.add(group); // BOTH subscription if (!server.isLocal(userToUpdate)) { // Set subscription type to BOTH if the roster user belongs to a shared group for (Group group : userGroups) { // Susbcribe to the presence of the remote user. This is only necessary for ! 4 // that is mutually visible with a shared group of the new roster item if (!group.isUser(addedUser) && rosterManag // remote users and may only work with remote users that **automatically** if (rosterManager.hasMutualVisibility(getUsername(), userGroups, addedUser, sharedGroups)) { // Add the shared group to the list of invisible shared g // accept presence subscription requests item.setSubStatus(RosterItem.SUB_BOTH); item.addInvisibleSharedGroup(group); sendSubscribeRequest(addedUser, userToUpdate, true);
Recommend
More recommend