ifparentNodeKey != null && foundParentNodeKey {try {// needs test and finishing, especiallypathToSubTreeRootNode argument loadXMLSubTreeIntoForestHashtablenode, parentNodeKey,bonForumXML
Trang 1if(pathToSubTreeRootNode == null || pathToSubTreeRootNode.length() <1) {
pathToSubTreeRootNode = “”;
}parentNodeInDestination = parentNodeInDestination.trim();
if(parentNodeInDestination == null || parentNodeInDestination.length()
< 1) {
parentNodeInDestination = “things”;
}// parse documenttry {
DOMParser parser = new DOMParser();
parser.parse(xmlUri);
Document document = parser.getDocument();
try {loadForumXML(pathToSubTreeRootNode,parentNodeInDestination, document, “pathNameHashtable”, sessionId);
}catch(Exception ee) {log(sessionId, “err”, “caught exception trying to loadinto bonForumXML: “+ xmlUri);
}}catch(Exception ex) {log(sessionId, “err”, “caught exception trying to parse: “ +xmlUri);
}}/** Loads XML from URI into “bonBufferXML” ForestHashtable member
*
*
* @param pathToSubTreeRootNode String
* @param xmlUri String
* @param nodeKeyHashtableName String
* @param sessionId String
*/
protected void loadBufferXMLFromURI(String pathToSubTreeRootNode, StringparentNodeInDestination, String xmlUri, String nodeKeyHashtableName, StringsessionId) {
if(parentNodeInDestination == null || parentNodeInDestination.length()
< 1) {
parentNodeInDestination = “things”;
}// parse documenttry {
Trang 2DOMParser parser = new DOMParser();
parser.parse(xmlUri);
Document document = parser.getDocument();
try {loadBufferXML(pathToSubTreeRootNode,parentNodeInDestination, document, “pathNameHashtable”, sessionId);
}catch(Exception ee) {log(sessionId, “err”, “caught exception trying to loadinto bonBufferXML: “+ xmlUri);
}}catch(Exception ex) {log(sessionId, “err”, “caught exception trying to parse: “ +xmlUri);
}}/** Loads XML from DOM node into “bonForumXML” ForestHashtable member
*
*
* @param pathToSubTreeRootNode String
* @param parentNodeInDestination String
* @param node Node
* @param nodeKeyHashtableName String
* @param sessionId String
*/
protected void loadForumXML(String pathToSubTreeRootNode, StringparentNodeInDestination, Node node, String nodeKeyHashtableName, String sessionId){
Object parentNodeKey = null;
String nodeKeyPathName = “”;
boolean foundParentNodeKey = true; // assume successif(parentNodeInDestination.equals(“actors”)) {parentNodeKey = (Object)getActorsNodeKey();
}else if(parentNodeInDestination.equals(“actions”)) {parentNodeKey = (Object)getActionsNodeKey();
}else if(parentNodeInDestination.equals(“things”)) {parentNodeKey = (Object)getThingsNodeKey();
}else {if(getBonForumXML().getNodeNameHashtable().containsKey(parentNodeInDestination)) {
parentNodeKey =getBonForumXML().getNodeNameHashtable().get(parentNodeInDestination);
}else {foundParentNodeKey = false;
}}
Trang 3if(parentNodeKey != null && foundParentNodeKey) {try {
// needs test and finishing, especiallypathToSubTreeRootNode argument
loadXMLSubTreeIntoForestHashtable(node, parentNodeKey,bonForumXML, nodeKeyPathName, nodeKeyHashtableName, sessionId);
}catch(Exception ee) {log(sessionId, “err”, “loadForumXML() caught Exceptioninvoking loadXMLSubTreeIntoForestHashtable()”);
}}}/** Loads XML from DOM node into the bonBufferXML ForestHashtable
*
*
* @param pathToSubTreeRootNode String
* @param parentNodeInDestination String
* @param node Node
* @param nodeKeyHashtableName String
* @param sessionId String
*/
protected void loadBufferXML(String pathToSubTreeRootNode, StringparentNodeInDestination, Node node, String nodeKeyHashtableName, String sessionId){
Object parentNodeKey = null;
String nodeKeyPathName = “”;
boolean foundParentNodeKey = true; // assume successif(parentNodeInDestination.equals(“actors”)) {parentNodeKey = (Object)getBufferActorsNodeKey();
}else if(parentNodeInDestination.equals(“actions”)) {parentNodeKey = (Object)getBufferActionsNodeKey();
}else if(parentNodeInDestination.equals(“things”)) {parentNodeKey = (Object)getBufferThingsNodeKey();
}else {if(bonBufferXML.getNodeNameHashtable().containsKey(parentNodeInDestination)) {
parentNodeKey =bonBufferXML.getNodeNameHashtable().get(parentNodeInDestination);
}else {foundParentNodeKey = false;
}}if(parentNodeKey != null && foundParentNodeKey) {try {
// needs test and finishing, especiallypathToSubTreeRootNode argument
Trang 4loadXMLSubTreeIntoForestHashtable(node, parentNodeKey,bonBufferXML, nodeKeyPathName, nodeKeyHashtableName, sessionId);
}catch(Exception ee) {log(sessionId, “err”, “loadBufferXML() caught Exceptioninvoking loadXMLSubTreeIntoForestHashtable()”);
}}}/** Loads the specified node, recursively, into a ForestHashtable
* NOTE: only loads element nodes with attributes, and any text nodechildren
*
* @param node Node
* @param parentNodeKey Object
* @param forestHashtable ForestHashtable
* @param nodeKeyPathName String
* @param nodeKeyHashtableName String
* @param sessionId String
*/
protected void loadXMLSubTreeIntoForestHashtable(Node node, ObjectparentNodeKey, ForestHashtable forestHashtable, String nodeKeyPathName, StringnodeKeyHashtableName, String sessionId) {
}// the ForestHashtable instance must exist for this method to workint type = node.getNodeType();
switch(type) {// process document nodecase Node.DOCUMENT_NODE: {loadXMLSubTreeIntoForestHashtable(((Document)node).getDocumentElement(),parentNodeKey, forestHashtable, nodeKeyPathName, nodeKeyHashtableName, sessionId);
break;
}// process element with attributes, and also get text nodes for contentcase Node.ELEMENT_NODE: {
nodeName = node.getNodeName();
// LATER: here can wait for element named bypathToSubTreeRootNode, ignoring ancestors
Attr attrs[] =BonForumUtils.sortAttributes(node.getAttributes());
nodeAttributes = “”;
for ( int i = 0; i < attrs.length; i++ ) {Attr attr = attrs[i];
Trang 5nodeAttributes += (“ “);
nodeAttributes += (attr.getNodeName());
nodeAttributes += (“=\””);
nodeAttributes += (normalize(attr.getNodeValue()));nodeAttributes += (“\””);
}// adds node and gets its nodeKeyBonNode bonNode;
bonNode = forestHashtable.addChildNodeToNonRootNode(nodeName,nodeAttributes, nodeContent, (NodeKey)parentNodeKey, nodeKeyHashtableName,sessionId);
nextParentNodeKey =(Object)forestHashtable.nodeKeyFromBonNode(bonNode);
// optionally save nodeKey in a hashtable to use for fastlookups, pathname sorting, etc
if(nodeKeyHashtableName != null && nodeKeyHashtableName != “”) {if(nodeKeyHashtableName.equals(“pathNameHashtable”)) {// here optionally save nodeKey with a pathName key// only save descendants of bonForum.things.subjects
if (nodeKeyPathName.equals(“”)) {if( (!(nodeName.equals(“bonForum”))) &&(!(nodeName.equals(“things”))) &&(!(nodeName.equals(“subjects”))) ) {nodeKeyPathName = nodeName;
}}
else {// build the pathName by concatenating nodejust added
nodeKeyPathName = nodeKeyPathName + “.” +nodeName;
}if(!nodeKeyPathName.equals(“”)) {forestHashtable.getPathNameHashtable().put(nodeKeyPathName, nextParentNodeKey);
}}else {// later we can add other types of hashtables here}
}// here we get text nodes for our content, and recursively visitelement descendants
// we are ignoring ENTITY_REFERENCE_NODE, CDATA_SECTION_NODE,PROCESSING_INSTRUCTION_NODE
NodeList children = node.getChildNodes();
if ( children != null ) {int len = children.getLength();
for ( int i = 0; i < len; i++ ) {
// get text if any, else recursively visit elementchildren
Trang 6int nodeType = children.item(i).getNodeType();
if(nodeType == Node.TEXT_NODE) {nodeContent += “ “ +normalize(children.item(i).getNodeValue().trim());
}else if(nodeType == Node.ELEMENT_NODE) {// recursion to visit all subnodesloadXMLSubTreeIntoForestHashtable(children.item(i),nextParentNodeKey, forestHashtable, nodeKeyPathName, nodeKeyHashtableName,sessionId);
}}
}// edit the node to add content from text nodenodeContent = nodeContent.trim();
if(nodeContent.length() > 0) {NodeKey nk =
getBonForumXML().editBonNode((NodeKey)(nextParentNodeKey), null, null,nodeContent);
}break;
} // end case Node.ELEMENT_NODE} // end switch
}/** Adds a node to “bonForumXML” ForestHashtable member
*
* @param command = “bonAddElement” (others could follow)
* @param parentNodeKeyKey String
* @param nameAndAttributes String
* @param content String
* @param forestHashtableName String
* @param nodeKeyHashtableName String
* @param sessionId String
* @return Object that can be cast to a NodeKey
*/
protected Object add(String command, String parentNodeKeyKey, StringnameAndAttributes, String content, String forestHashtableName, StringnodeKeyHashtableName, String sessionId) {
BonNode bonNode = new BonNode();
NodeKey nonRootNodeKey = new NodeKey();
nonRootNodeKey = (NodeKey)addNode(bonNode, nonRootNodeKey,command, parentNodeKeyKey, nameAndAttributes, content, forestHashtableName,nodeKeyHashtableName, sessionId);
return (Object)(nonRootNodeKey);
}/** Adds a node to “bonBufferXML” ForestHashtable member
*
* @param command = “bonAddElement” (others could follow)
* @param parentNodeKeyKey String
* @param nameAndAttributes String
* @param content String
Trang 7* @param forestHashtableName String
* @param nodeKeyHashtableName String
* @param sessionId String
* @return Object that can be cast to a NodeKey
*/
protected Object addToBuffer(String command, String parentNodeKeyKey, StringnameAndAttributes, String content, String forestHashtableName, String
nodeKeyHashtableName, String sessionId) {
BonNode bonNode = new BonNode();
NodeKey nonRootNodeKey = new NodeKey();
nonRootNodeKey = (NodeKey)addNode(bonNode, nonRootNodeKey,command, parentNodeKeyKey, nameAndAttributes, content, forestHashtableName,nodeKeyHashtableName, sessionId);
return (Object)(nonRootNodeKey);
}/** Adds a node to “bonForumXML”, or “bonBufferXML”, or otherForestHashtable
*
* @param bonNode BonNode
* @param nonRootNodeKey NodeKey
* @param command String =”bonAddElement”(others could follow)
* @param parentNodeKeyKey String
* @param nameAndAttributes String
* @param content String
* @param forestHashtableName String
* @param nodeKeyHashtableName String
* @param sessionId String
* @return Object that can be cast to a NodeKey
*/
protected Object addNode(BonNode bonNode, NodeKey nonRootNodeKey, Stringcommand, String parentNodeKeyKey, String nameAndAttributes, String content, StringforestHashtableName, String nodeKeyHashtableName, String sessionId) {
boolean fast = false;
ForestHashtable forestHashtable;
if(forestHashtableName.equals(“bonForumXML”)) {forestHashtable = bonForumXML;
if (parentNodeKeyKey.equals(“actors”)) {nonRootNodeKey = getActorsNodeKey();
fast = true;
}else if (parentNodeKeyKey.equals(“actions”)) {nonRootNodeKey = getActionsNodeKey();
fast = true;
}else if (parentNodeKeyKey.equals(“things”)) {nonRootNodeKey = getThingsNodeKey();
fast = true;
}}else if(forestHashtableName.equals(“bonBufferXML”)) {
Trang 8forestHashtable = bonBufferXML;
if (parentNodeKeyKey.equals(“actors”)) {nonRootNodeKey = getBufferActorsNodeKey();
fast = true;
}else if (parentNodeKeyKey.equals(“actions”)) {nonRootNodeKey = getBufferActionsNodeKey();
fast = true;
}else if (parentNodeKeyKey.equals(“things”)) {nonRootNodeKey = getBufferThingsNodeKey();
fast = true;
}}else {forestHashtable = null;
}
if (command.equals(“bonAddElement”)) {try {
if(!fast) { // not a “fast” parent nodeKey//
// There are two possibilities (more later):
Trang 9if(nodeKeyHashtableName.equals(“pathNameHashtable”)){
if(forestHashtable.getPathNameHashtable().containsKey(parentNodeKeyKey)) {
nonRootNodeKey =(NodeKey)forestHashtable.getPathNameHashtable().get(parentNodeKeyKey);
}else {log(sessionId, “err”, “add() DID NOT FINDparentNodeKeyKey IN pathNameHashtable: “ + parentNodeKeyKey);
}}// The key should be in <sessionId:nodeName> format// we could later check the incoming sessionIdprefix is valid
// using isRequestedSessionIdValid(prefix)else if
(nodeKeyHashtableName.equals(“nodeNameHashtable”)) {
String temp = “” +forestHashtable.getNodeNameHashtable().size();
if(forestHashtable.getNodeNameHashtable().containsKey(parentNodeKeyKey)) {
nonRootNodeKey =(NodeKey)forestHashtable.getNodeNameHashtable().get(parentNodeKeyKey);
}else {log(sessionId, “err”, “add() DID NOTFIND parentNodeKeyKey IN nodeNameHashtable: “ + parentNodeKeyKey);
}}else {log(sessionId, “err”, “UNRECOGNIZEDnodeKeyHashtableName in add(): “ + parentNodeKeyKey);
}}try {if(nonRootNodeKey != null) {if(nonRootNodeKey.aKey != null &&
nonRootNodeKey.aKey.length() > 0) {
String name = “”;
String attributes = “”;
if(nameAndAttributes == null) {nameAndAttributes = “”;
}int inx =nameAndAttributes.trim().indexOf(‘ ‘);
if (inx > -1) { // space between name andattributes
name =nameAndAttributes.substring(0, inx);
Trang 10attributes =nameAndAttributes.substring(inx).trim();
}else {name = nameAndAttributes;
}bonNode =forestHashtable.addChildNodeToNonRootNode(name, attributes, content,nonRootNodeKey, nodeKeyHashtableName, sessionId);
}}}catch (Exception ex) {log(sessionId, “err”, “addChildNodeToNonRootNode()caused exception in add()”);
}}catch (Exception ee) {log(sessionId, “err”, “Exception in add()”);
}}return (Object)(bonNode.nodeKey);
}/** Removes a (session-dependent) node from “bonForumXML” ForestHashtablemember
* @param command String = “bonRemoveElement” (others later)
* @param nodeKeyKey String
* @param leafOnly String if uppercased is “TRUE” nodes withchildren not removed
* @param forestHashtableName String
* @param command String = “bonRemoveElement” (others later)
* @param nodeKeyKey String
* @param leafOnly String if uppercased is “TRUE” nodes withchildren not removed
* @param forestHashtableName String
* (for now: only non-global nodes removed)
* @param command String = “bonRemoveElement” (others later)
* @param nodeKeyKey String
Trang 11* @param leafOnly String if uppercased is “TRUE” nodes withchildren not removed
* @param forestHashtableName String
*/
protected void removeNode (String command, String nodeKeyKey, StringleafOnly, String forestHashtableName) {
NodeKey nonRootNodeKey = new NodeKey();
boolean fast = false;
// For now: just a choice between existing ForestHashtable instancesForestHashtable forestHashtable = null;
if(forestHashtableName.equals(“bonForumXML”)) {forestHashtable = bonForumXML;
if (nodeKeyKey.equals(“actors”)) {nonRootNodeKey = getActorsNodeKey();
fast = true;
}else if (nodeKeyKey.equals(“actions”)) {nonRootNodeKey = getActionsNodeKey();
fast = true;
}else if (nodeKeyKey.equals(“things”)) {nonRootNodeKey = getThingsNodeKey();
fast = true;
}}else if(forestHashtableName.equals(“bonBufferXML”)) {
if (nodeKeyKey.equals(“actors”)) {nonRootNodeKey = getBufferActorsNodeKey();
fast = true;
}else if (nodeKeyKey.equals(“actions”)) {nonRootNodeKey = getBufferActionsNodeKey();
fast = true;
}else if (nodeKeyKey.equals(“things”)) {nonRootNodeKey = getBufferThingsNodeKey();
fast = true;
}}NodeKey nodeKey = new NodeKey();
if (command.equals(“bonRemoveElement”)) {try {
if(!fast) {// does not have a “fast” global parent nodeKey// For now, only non-fast nodes can be removed!//
// Each NodeKey instance is saved innodeNameHashtable
// “fast” nodes have a nodeKeyKey of// “actors”, “actions”, or “things”,// “non-fast” nodes hava a nodeKeyKey
Trang 12// (a key into the nodeNameHashtable)// with a key format that is either:
// sessionId_creationTimeInMillis:nodeName// or, optionally:
// sessionId:nodeName// We could later check the incoming sessionIdprefix
// is valid using isRequestedSessionIdValid(prefix)if
(forestHashtable.getNodeNameHashtable().containsKey(nodeKeyKey)) {
nodeKey =(NodeKey)forestHashtable.getNodeNameHashtable().get(nodeKeyKey);
}}try {if(nodeKey.aKey != null && nodeKey.aKey.length() >
0) {
boolean deleteLeafOnly = false;
if(leafOnly.equalsIgnoreCase(“TRUE”)) {deleteLeafOnly = true;
}forestHashtable.deleteNode((NodeKey)nodeKey,deleteLeafOnly);
}}catch (Exception ex) {log(sessionId, “err”, “deleteNode() caused exception
in remove()”);
}}catch (Exception ee) {log(sessionId, “err”, “Exception in remove()”);
}}}/** Gets the NodeKey for a pathName in a pathNameHashtable
* (The NodeKey for each element in the “subjects” subtree
* is also in a pathNameHashtable, with a pathName key)
*
* @param pathName String
* @param pathNameHashtable PathNameHashtable
* @return NodeKey for the pathName
* (The subject pathName is a key value for a NodeKey in aPathNameHashtable)
*
Trang 13* @param pathName String
* @param pathNameHashtable PathNameHashtable
* @param forestHashtable ForestHashtable
* @return NodeKey for the pathName
}else {return(null);
}}/** Returns the pathName to a NodeKey in a ForestHashtable
*
* @param nodeKey NodeKey
* @param forestHashtable ForestHashtable
* @return The pathName for the nodeKey as a String
*/
public String pathNameFromNodeKey(NodeKey nodeKey, ForestHashtableforestHashtable)
{String temp = “”;
BonNode bonNode;
NodeKey parentNodeKey;
try {bonNode = forestHashtable.getBonNode(nodeKey);
temp = bonNode.nodeName;
parentNodeKey = bonNode.parentNodeKey;
boolean done = false;
while (!done) {if(bonNode.parentNodeKey.aKey.equals(“”)) {done = true;
break;
}else {bonNode = forestHashtable.getBonNode(parentNodeKey);temp = bonNode.nodeName + “.” + temp;
parentNodeKey = bonNode.parentNodeKey;
}}}catch(Exception ee) {log(sessionId, “err”, “Exception caught inpathNameFromNodeKey()”);
}return temp;
}
Trang 14/** Returns the pathKey to a NodeKey in a ForestHashtable.
* A pathKey is made up of the combined nodeKeys of all the nodes from theroot
* to the nodeKey argument
* Each nodeKey is a triple-valued key used by a ForestHashtable
* An Example of a pathKey is:
* 827347382374
238493049323-384930493039-584954059453.463748293847-564738473623-* The nodeKeys is a pathKey are separated by a period, ‘.’, and the
* AKey, BKey and CKey in each nodeKey are separated by a dash, ‘-’
*
* @param nodeKey NodeKey
* @param forestHashtable ForestHashtable
* @return The pathKey for the nodeKey as a String
temp = bonNode.nodeKey.aKey + “-” + bonNode.nodeKey.bKey + “-” +bonNode.nodeKey.cKey;
parentNodeKey = bonNode.parentNodeKey;
boolean done = false;
while (!done) {bonNode = forestHashtable.getBonNode(parentNodeKey);
temp = bonNode.nodeKey.aKey + “-” + bonNode.nodeKey.bKey +
“-” + bonNode.nodeKey.cKey + “.” + temp;
if(bonNode.parentNodeKey.aKey.equals(“”)) {done = true;
break;
}else {parentNodeKey = bonNode.parentNodeKey;
}}}catch(Exception ee) {log(sessionId, “err”, “Exception caught inpathKeyFromNodeKey()”);
}return temp;
}/** Outputs pathNames and nodeKeys from a bonForumXML subTree as a TreeMap
* (except for chatItems!)
* The TreeMap can be used as a sorted list of the paths to all the nodes
*
* NOTE: if you need method to output chatItem elements,
* You can add an option arg to do that!
Trang 15* (chatItem elements have names that are equal to:
* “sessionID_” + chatCreatorHostSessionId +chatNodeCreationTimeInMillis),
*
* @param command String (unused, available argument)
* @param pathToSubTreeRootNode String
* @param option1 String (reserved argument)
* @param option2 String (reserved argument)
}else {TreeMap errorTreeMap = new TreeMap();
errorTreeMap.put(“0”, “::::::::::::error incommand::::::::::::::”);
return errorTreeMap; // later this error causesexception?
}}log(sessionId, “err”, “Hello, outputForumPathNames!”);
BonNode bonNode = null;
NodeKey nodeKey = new NodeKey();
TreeMap outputTreeMap = new TreeMap();
Enumeration enumeration = getBonForumXML().elements();
while(enumeration.hasMoreElements()) {bonNode = (BonNode)enumeration.nextElement();
// and we want to suppress these in users display of forumpathNames (e.g., chat subjects)
if (pathToSubTreeRootNode != null &&
pathToSubTreeRootNode.length() > 0) {
if(bonNode.nodeAttributes.indexOf(“chatTopic=\””) < 0) {if(pathName.indexOf(pathToSubTreeRootNode) == 0) {// strip off leftmost nodes
pathName =pathName.substring(pathToSubTreeRootNode.length());
// strip off period separator
Trang 16if(pathName.indexOf(“.”) == 0) {pathName = pathName.substring(1);
}if(pathName.length() > 0) {outputTreeMap.put(pathName,nodeKey.aKey);
}}}}else {if(pathName.length() > 0) {outputTreeMap.put(pathName, nodeKey.aKey);
}}}if(outputTreeMap.size()<1) {outputTreeMap.put(“.”, “0”); // these are empty output returnvalues
}log(sessionId, “err”, “Goodbye, outputForumPathNames!”);
return outputTreeMap;
}/** Outputs pathNames and nodeKeys from a bonBufferXML subTree as a TreeMap
* The TreeMap can be used as a sorted list of the paths to all the nodes
*
* @param command String (reserved argument, available fromChoiceTag)
* @param pathToSubTreeRootNode String
* @param option1 String (reserved argument, available fromChoiceTag)
* @param option2 String (reserved argument, available fromChoiceTag)
sub-BonNode bonNode = null;
NodeKey nodeKey = new NodeKey();
TreeMap outputTreeMap = new TreeMap();
Enumeration enumeration = bonBufferXML.elements();
while(enumeration.hasMoreElements()) {bonNode = (BonNode)enumeration.nextElement();
Trang 17outputForumPathNames)
outputTreeMap.put(pathName, nodeKey.aKey);
}if(outputTreeMap.size()<1) {outputTreeMap.put(“.”, “0”); // these are empty output returnvalues
}return outputTreeMap;
}/** Outputs the messages in the session’s current chat from bonForumXML as aTreeMap
* The TreeMap can be used as a sorted list of the messages for thatsession’s chat
}else {TreeMap errorTreeMap = new TreeMap();
errorTreeMap.put(“0”, “::::::::::::error incommand::::::::::::::”);
return errorTreeMap; // later this error causesexception?
}}String messageTimeMillis = “”;
BonNode bonNode = null;
TreeMap outputTreeMap = new TreeMap();
TreeMap tempTreeMap = new TreeMap(Collections.reverseOrder());Enumeration enumeration = getBonForumXML().elements();
// get this session’s itemKey (chat subject category) from sessionAttribute
Trang 18String itemKey = normalize((String)session.getAttribute(“itemKey”));
if(itemKey.trim().length() < 1) {log(sessionId, “err”, “outputForumChatMessages() ERROR: sessionhas no itemKey!”);
}else {// get all messages that have this chat’s itemKeywhile(enumeration.hasMoreElements()) {
// get bonNode and its name, attributes and contentbonNode = (BonNode)enumeration.nextElement();
String name = bonNode.nodeName;
String attributes = bonNode.nodeAttributes;
String content = bonNode.nodeContent;
// if the bonNode is a messageif(name.equals(“message”)) {/* THESE WERE DEBUGGING TESTS FOR getAttributeValue// test value with escaped double quote in it (xmlerror!)
String testStr =getBonForumXML().getAttributeValue(attributes, “type”);
//log(sessionId, “”, “outputForumChatMessages(),testStr: “ + testStr);
// test attribute value not there (programmingerror)
testStr =getBonForumXML().getAttributeValue(attributes, “notThere”);
//log(sessionId, “”, “outputForumChatMessages(),testStr: “ + testStr);
// test value without closing double quote (xmlerror)
testStr =getBonForumXML().getAttributeValue(attributes, “test1”);
//log(sessionId, “”, “outputForumChatMessages(),testStr: “ + testStr);
*/
// get itemKey attribute valueString messageItemKey =getBonForumXML().getAttributeValue(attributes, “itemKey”);
if(messageItemKey == null) {// error, handle laterlog(sessionId, “err”,
“outputForumChatMessages(), ERROR! NO ItemKey found in message attributes!”);
continue;
}// if its this session’s itemKey, it is also thissession’s chat
if(messageItemKey.equals(itemKey)) {// get message timeMillis attribute valuemessageTimeMillis =
getBonForumXML().getAttributeValue(attributes, “timeMillis”);
if(messageTimeMillis == null) {
Trang 19// error, handle laterlog(sessionId, “err”,
“outputForumChatMessages(), ERROR! NO timeMillis found in message attributes!”);
continue;
}}else {continue;
}// assume content is “<normalized actorNickname>:: “followed by chatMessage
// put content in TreeMap with timeMillis as keytempTreeMap.put(messageTimeMillis, content);} // end if
} // end while} // end else// keep track of last message by its timesession.setAttribute(“lastMessageTimeMillis”, messageTimeMillis);// should we make sure here that currentTimeMillis is > largestmessageTimeMillis?
// the TreeMap chatHistoryTreeMap now contains the sorted chat lines// ready to be put into the “output” choiceTag attribute,
// in a manner analogous to that use in the “bonOutputTable” choiceTagcommand
// Here we get a sorted subset of the messages according to sessionattributes
// This allows user to set size of output and page through messages// messages array gets sorted message times in reverse orderString[] messages = (String[]) tempTreeMap.keySet().toArray(newString[0]);
// keep track of how many there were at this output timeint numberOfMessages = messages.length;
String quantity =(String)session.getAttribute(“chatMessagesPageSize”);
if (quantity == null) {log(sessionId, “err”, “outputForumChatMessages(), quantity ==null”);
quantity = “10”; // initialize}
int numberPerPage = -1;
try {numberPerPage = Integer.parseInt(quantity);
}catch (NumberFormatException nFE) {log(sessionId, “err”, “outputForumChatMessages(), cannot parsequantity requested as int: “ + quantity);
numberPerPage = 10;
}if(numberPerPage > numberOfMessages) {numberPerPage = numberOfMessages;
}
Trang 20int numberOfPages = 0;
try {numberOfPages = (numberOfMessages / numberPerPage);
if((numberOfMessages % numberPerPage) != 0) {++numberOfPages;
}}catch(Exception ee) {numberOfPages = 0;
}session.setAttribute(“chatNumberOfPages”,Integer.toString(numberOfPages));
String pagesFromEnd = (String)session.getAttribute(“pagesFromEnd”);
int pagesToSkip = -1;
try {pagesToSkip = Integer.parseInt(pagesFromEnd);
}catch (NumberFormatException nFE) {log(sessionId, “err”, “outputForumChatMessages(), cannot parsesession attribute pagesFromEnd: “ + pagesFromEnd);
pagesToSkip = -1;
}if(pagesToSkip >= numberOfPages) {pagesToSkip = numberOfPages - 1;
}int pageNumber = numberOfPages - pagesToSkip;
if(pageNumber > numberOfPages) {pageNumber = numberOfPages;
}session.setAttribute(“chatPageNumber”, Integer.toString(pageNumber));
String navigation;
try {navigation =(String)session.getAttribute(“chatMessagesNavigator”);
if(!navigation.equals(“same”) && !navigation.equals(“first”) &&
!navigation.equals(“previous”) && !navigation.equals(“next”) &&
!navigation.equals(“last”)) {
navigation = “last”;
}}catch(Exception ee) {log(sessionId, “err”, “outputForumChatMessages(), no sessionattribute chatMessagesNavigator, using \”last\””);
navigation = “last”;
session.setAttribute(“chatMessagesNavigator”, “last”);
}// We have reversed the sort order of messages in tempTreeMap,// therefore these navigation cases will seem to be backwards!
// Also, it means that if there are more than one page of messages,// then the first page of messages may be less than full,
// while the last will stay full (This is more convenient, since the
Trang 21// case is to display the last page after each refresh, and this// way the user sees more messages most of the time Later we could// implement scrolling by the message instead of by the page.)if(navigation.equalsIgnoreCase(“previous”)) {
++pagesToSkip;
if(pagesToSkip >= numberOfPages) {pagesToSkip = numberOfPages - 1;
}session.setAttribute(“chatMessagesNavigator”, “same”);
}else if(navigation.equalsIgnoreCase(“next”)) {
—pagesToSkip;
if(pagesToSkip < 0 ) {pagesToSkip = 0;
}session.setAttribute(“chatMessagesNavigator”, “same”);
}else if(navigation.equalsIgnoreCase(“last”)) {pagesToSkip = 0;
}else if(navigation.equalsIgnoreCase(“first”)) {pagesToSkip = numberOfPages - 1;
}// If we are not showing last page of messages, we do not want list torefresh
// because messages coming into chat from other guests or host willscroll
// the messages That is ok only when user is looking at last messagein
// display Otherwise, it is confusing and irritating!
// So, let’s control the robot applet’s refresh action here:
String noScrolling = “same;first;previous;next”;
if(noScrolling.indexOf(navigation) > -1) {session.setAttribute(“refresh”, “false”);
}else {session.setAttribute(“refresh”, “true”);
}session.setAttribute(“pagesFromEnd”, Integer.toString(pagesToSkip));int numberToSkip = numberPerPage * pagesToSkip;
if(navigation.equalsIgnoreCase(“same”)) {String lastNumOfMessages =
normalize((String)session.getAttribute(“numberOfMessages”));
try {int lastNumberOfMessages =Integer.parseInt(lastNumOfMessages);
int numberOfNewMessages = numberOfMessages lastNumberOfMessages;
-numberToSkip += numberOfNewMessages;
}
Trang 22catch(Exception ee) {}
}if(numberToSkip > numberOfMessages) {numberToSkip = numberOfMessages;
}session.setAttribute(“numberOfMessages”,Integer.toString(numberOfMessages));
int ii;
for(ii = 0; ii < numberToSkip; ++ii);
if((numberOfMessages - numberToSkip) < numberPerPage) {numberPerPage = numberOfMessages - numberToSkip;
}int jj;
for(jj = ii; jj < ii + numberPerPage; ++jj) {outputTreeMap.put(messages[jj], tempTreeMap.get(messages[jj]));
}String lastMNO = Integer.toString(jj-1);
session.setAttribute(“lastMessageNumberOutput”, lastMNO);
if(outputTreeMap.size()<1) {outputTreeMap.put(“0”, “::::::::::::emptychat:::::::::::::::::::”);
}return outputTreeMap;
}/** Outputs the messages in the session’s current chat from bonBufferXML as
BonNode bonNode = null;
TreeMap outputTreeMap = new TreeMap();
TreeMap tempTreeMap = new TreeMap(Collections.reverseOrder());
Trang 23Enumeration enumeration = bonBufferXML.elements();
// get this session’s itemKey (chat subject category) from sessionAttribute
String itemKey = normalize((String)session.getAttribute(“itemKey”));if(itemKey.trim().length() < 1) {
log(sessionId, “err”, “outputBufferChatMessages() ERROR: sessionhas no itemKey!”);
}else {// get all messages that have this chat’s itemKeywhile(enumeration.hasMoreElements()) {
// get bonNode and its name, attributes and contentbonNode = (BonNode)enumeration.nextElement();
String name = bonNode.nodeName;
String attributes = bonNode.nodeAttributes;
String content = bonNode.nodeContent;
// if the bonNode is a messageif(name.equals(“message”)) {/* THESE WERE DEBUGGING TESTS FOR getAttributeValue// test value with escaped double quote in it (xmlerror!)
String testStr =bonBufferXML.getAttributeValue(attributes, “type”);
//log(sessionId, “”, “outputBufferChatMessages(),testStr: “ + testStr);
// test attribute value not there (programmingerror)
testStr = bonBufferXML.getAttributeValue(attributes,
“notThere”);
//log(sessionId, “”, “outputBufferChatMessages(),testStr: “ + testStr);
// test value without closing double quote (xmlerror)
testStr = bonBufferXML.getAttributeValue(attributes,
“test1”);
//log(sessionId, “”, “outputBufferChatMessages(),testStr: “ + testStr);
*/
// get itemKey attribute valueString messageItemKey =bonBufferXML.getAttributeValue(attributes, “itemKey”);
if(messageItemKey == null) {// error, handle laterlog(sessionId, “err”,
“outputBufferChatMessages(), ERROR! NO ItemKey found in message attributes!”);
continue;
}// if its this session’s itemKey, it is also thissession’s chat
if(messageItemKey.equals(itemKey)) {// get message timeMillis attribute value
Trang 24messageTimeMillis =bonBufferXML.getAttributeValue(attributes, “timeMillis”);
if(messageTimeMillis == null) {// error, handle laterlog(sessionId, “err”,
“outputBufferChatMessages(), ERROR! NO timeMillis found in message attributes!”);
continue;
}}else {continue;
}// assume content is “<normalized actorNickname>:: “followed by chatMessage
// put content in TreeMap with timeMillis as keytempTreeMap.put(messageTimeMillis, content);
} // end if} // end while} // end else// keep track of last message by its timesession.setAttribute(“lastMessageTimeMillis”, messageTimeMillis);
// should we make sure here that currentTimeMillis is > largestmessageTimeMillis?
// the TreeMap chatHistoryTreeMap now contains the sorted chat lines// ready to be put into the “output” choiceTag attribute,
// in a manner analogous to that use in the “bonOutputTable” choiceTagcommand
// Here we get a sorted subset of the messages according to sessionattributes
// This allows user to set size of output and page through messages// messages array gets sorted message times in reverse orderString[] messages = (String[]) tempTreeMap.keySet().toArray(newString[0]);
// keep track of how many there were at this output timeint numberOfMessages = messages.length;
String quantity =(String)session.getAttribute(“chatMessagesPageSize”);
if (quantity == null) {log(sessionId, “err”, “outputBufferChatMessages(), quantity ==
null”);
quantity = “10”; // initialize}
int numberPerPage = -1;
try {numberPerPage = Integer.parseInt(quantity);
}catch (NumberFormatException nFE) {
log(sessionId, “err”, “outputBufferChatMessages(), cannotparse quantity requested as int: “ + quantity);
numberPerPage = 10;
}
Trang 25if(numberPerPage > numberOfMessages) {numberPerPage = numberOfMessages;
}int numberOfPages = 0;
try {numberOfPages = (numberOfMessages / numberPerPage);
if((numberOfMessages % numberPerPage) != 0) {++numberOfPages;
}}catch(Exception ee) {numberOfPages = 0;
}session.setAttribute(“chatNumberOfPages”,Integer.toString(numberOfPages));
String pagesFromEnd = (String)session.getAttribute(“pagesFromEnd”);if(pagesFromEnd.equals(“null”)) {
pagesFromEnd = “0”;
}int pagesToSkip = -1;
try {pagesToSkip = Integer.parseInt(pagesFromEnd);
}catch (NumberFormatException nFE) {log(sessionId, “err”, “outputBufferChatMessages(), cannot parsesession attribute pagesFromEnd: “ + pagesFromEnd);
pagesToSkip = -1;
}if(pagesToSkip >= numberOfPages) {pagesToSkip = numberOfPages - 1;
}int pageNumber = numberOfPages - pagesToSkip;
if(pageNumber > numberOfPages) {pageNumber = numberOfPages;
}session.setAttribute(“chatPageNumber”, Integer.toString(pageNumber)); String navigation;
try {navigation =(String)session.getAttribute(“chatMessagesNavigator”);
if(!navigation.equals(“same”) && !navigation.equals(“first”) &&
!navigation.equals(“previous”) && !navigation.equals(“next”) &&
!navigation.equals(“last”)) {
navigation = “last”;
}}catch(Exception ee) {log(sessionId, “err”, “outputBufferChatMessages(), exceptiongetting session attribute chatMessagesNavigator, using \”last\””);
navigation = “last”;
}