XML, XSLT, Java, and JSP: A Case Study in Developing a Web Application- P13

Chia sẻ: Thanh Cong | Ngày: | Loại File: PDF | Số trang:50

0
61
lượt xem
24
download

XML, XSLT, Java, and JSP: A Case Study in Developing a Web Application- P13

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

XML, XSLT, Java, and JSP: A Case Study in Developing a Web Application- P13: Là một nhà phát triển Web, bạn biết những thách thức trong việc xây dựng các ứng dụng mạnh mẽ trên nhiều nền tảng. Tạo các ứng dụng di động trở nên thật sự có thể bằng cách sử dụng Java cho code và XML để tổ chức và quản lý dữ liệu. "XML, XSLT, Java, và JSP: Một trường hợp học" sẽ giúp bạn tối đa hóa khả năng của XML, XSLT, Java, và JSP trong các ứng dụng web của bạn....

Chủ đề:
Lưu

Nội dung Text: XML, XSLT, Java, and JSP: A Case Study in Developing a Web Application- P13

  1. 582 Appendix C Source Code for bonForum Web Application * XML document specification. * ForestHashtable is described fully in the book: * XML, XSLT, Java and JSP - A Case Study in Developing a Web Application, * by Westy Rockwell, published by * New Riders. * Translation to German published by * Galileo Press. * For further information visit the open source * BonForum Project on SourceForge * @author Westy Rockwell */ public class ForestHashtable extends java.util.Hashtable { private NodeNameHashtable nodeNameHashtable; private PathNameHashtable pathNameHashtable; private boolean lastRootNodeFound; private boolean lastChildOfRootNodeFound; // next one defined further down for recursion // private boolean lastChildOfNonRootNodeFound; private String currentRootNodeAKey; private String currentRootNodeBKey; private String currentRootNodeCKey; // for debug only private String currentChildOfRootNodeAKey; private String currentChildOfRootNodeBKey; private String currentChildOfRootNodeCKey; // for debug only // next 3 defined further down for recursion // private String currentChildOfNonRootNodeAKey; // private String currentChildOfNonRootNodeBKey; // private String currentChildOfNonRootNodeCKey; private static BonLogger logFH = null; // Controls logger output. private static String logging = null; // False until logger ready. private static boolean loggingInitialized = false; // for logging output, when no sessionId available private static String sessionId = “0000000000”; private static final int NO_NODEKEY_KEY_PREFIX = 0; private static final int SESSION_ID = 1; private static final int SESSION_ID_AND_CREATION_TIME = 2; private String uniqueNodeKeyKeyList = “message;messageKey”; /** Sets uniqueNodeKeyKeyList of node names unique per session * in nodeNameHashtable. Determines key prefix choice. * Node names in list can have one key per session * Node names not in list can have multiple keys per session * This saves space by not storing keys for unused nodeKey entries. * (Note: applies only adding children to non-root nodes.). * */ protected void setUniqueNodeKeyKeyList(String newUniqueNodeKeyKeyList) { uniqueNodeKeyKeyList = newUniqueNodeKeyKeyList; } /** Gets uniqueNodeKeyKeyList setting.
  2. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 583 * (see set method for details) * * @return String uniqueNodeKeyKeyList */ public String getUniqueNodeKeyKeyList() { return uniqueNodeKeyKeyList; } /** Creates a ForestHashtable with the default capacity. */ public ForestHashtable() { super(); nodeNameHashtable = new NodeNameHashtable(); pathNameHashtable = new PathNameHashtable(); } /** Creates a ForestHashtable of a given capacity. * * @param capacity initialCapacity of parent java.util.Hashtable */ public ForestHashtable(int capacity) { super(capacity); nodeNameHashtable = new NodeNameHashtable(); pathNameHashtable = new PathNameHashtable(); } private void log(String sessionId, String where, String what) { if(logging != null) { logFH.logWrite(System.currentTimeMillis(), sessionId, where, what); } } /** Gets logging setting. * * @return String logging */ public String getLogging() { return logging; } /** Sets logging setting. * * @param String setting for logger logtype (“none”,”all”,”std”,”file”) */ protected void setLogging(String newLogging) { logging = newLogging; synchronized(this) { if(!loggingInitialized) { System.err.println(“ForestHashtable init loggingInitialized:” + loggingInitialized); System.err.println(“ForestHashtable init logging:” + logging); if(logging != null) { logFH = new BonLogger(“ForestHashtableLog.txt”, logging);
  3. 584 Appendix C Source Code for bonForum Web Application System.err.println(“ForestHashtable init logFH:” + logFH); logFH.setLogging(newLogging); loggingInitialized = true; System.err.println(“ForestHashtable init loggingInitialized:” + loggingInitialized); } } } } /** Gets nodeNameHashtable. * @return NodeNameHashtable nodeNameHashtable */ protected NodeNameHashtable getNodeNameHashtable() { return nodeNameHashtable; } /** Gets pathNameHashtable. * @return PathNameHashtable pathNameHashtable */ protected PathNameHashtable getPathNameHashtable() { return pathNameHashtable; } /** Returns nodeKey from a BonNode, as an object. * * @param bonNode node whose key is returned * @return nodeKey of BonNode cast to an Object */ protected Object nodeKeyFromBonNode(BonNode bonNode) { return (Object)bonNode.nodeKey; } /** Provides a useable NodeKey with a unique default root key value. * * @return NodeKey instance with unique aKey, initialized as a root node key * (to use for non-root nodes, change bKey and cKey values) */ private NodeKey getNextAvailableNodeKey() { long temp = 0; long lastCurrentTimeMillis = System.currentTimeMillis(); NodeKey nodeKey = new NodeKey(); while (temp
  4. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 585 * * @param keyOfNodeToDelete nodeKey of BonNode to delete * @return boolean true if deleted, false otherwise */ private boolean doDeleteNode(NodeKey keyOfNodeToDelete) { // LATER: this will just mark node as deleted, // and a separate thread will scavenge deleted nodes. if (this.containsKey(keyOfNodeToDelete)) { this.remove(keyOfNodeToDelete); return true; } else { return false; } } /** Deletes a BonNode and its descendant nodes, given a nodeKey value. * * @param keyOfNodeToDelete nodeKey of BonNode to delete * @return boolean true if at least one node was deleted, false otherwise */ private boolean doDeleteNodeRecursive(NodeKey keyOfNodeToDelete) { // LATER: this will just mark node as deleted, // and a separate thread will scavenge deleted nodes. String parentAKey = keyOfNodeToDelete.aKey; NodeKey nodeKey = new NodeKey(); BonNode bonNode = null; Enumeration enumeration = this.elements(); if(!(enumeration.hasMoreElements())) { return false; // no elements to delete } while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); nodeKey = bonNode.nodeKey; if(nodeKey.bKey.equals(parentAKey)) { // found a child doDeleteNodeRecursive(nodeKey); } } bonNode = this.getBonNode(keyOfNodeToDelete); this.remove(keyOfNodeToDelete); return true; } /** Returns true if a BonNode has child nodes. * * @param parentNodeKey the node being tested for children * @return boolean true if at least one node was deleted, false otherwise */ protected boolean hasAtLeastOneChild(NodeKey parentNodeKey) { // in a ForestHashtable, children have nodeKey.bKey equal to the parent’s nodeKey.aKey
  5. 586 Appendix C Source Code for bonForum Web Application BonNode bonNode = null; String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); if(bonNode.nodeKey.bKey.equals(parentAKey)) { return true; } } return false; } /** Deletes a BonNode and possibly its descendant nodes, given a nodeKey value. * * @param keyOfNodeToDelete nodeKey of BonNode to delete * @param leafOnly boolean true to delete only if node has no children * false to delete node and any descendant nodes * @return boolean true if at least one node was deleted, false otherwise */ public boolean deleteNode(NodeKey keyOfNodeToDelete, boolean leafOnly) { // NodeKey is a three-valued key (ABCTable key). // if leafOnly is True, then Node not deleted if it has one or more child nodes. // if leafOnly is False, then Node and all its descendants are deleted! synchronized(this) { if(this.containsKey(keyOfNodeToDelete)) { if(leafOnly) { if(hasAtLeastOneChild(keyOfNodeToDelete)) { return false; // was not a leaf node, so not deleted } } // delete and report success or failure return doDeleteNodeRecursive(keyOfNodeToDelete); } else { return false; // no such node } } } /** Adds a BonNode (and optionally its nodeKey to another hashtable for fast lookups). * To add nodes, user only calls addRootNode, addChildNodeToRootNode or addChildNodeToNonRootNode. * If nodeKeyHashtableName is “nodeNameHashtable” then these nodeKeyKeyPrefix values are possible: * * NO_NODEKEY_KEY_PREFIX makes added node global, visible to all HTTP Sessions, * SESSION_ID makes node UNIQUE for nodeName in session, and visible
  6. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 587 only to current session * SESSION_ID_AND_CREATION_TIME allows multiple nodes with nodeName, and visible only to current session * * * Note: more values of nodeKeyKeyPrefix will be defined in later versions! * * @param nodeName String naming this node * @param nodeAttributes String containing all attributes concatenated (name=value name=value ...) * @param nodeContent String containing text content of node * @param nodeKey NodeKey uniquely identifying and positioning node to be added in hierarchy * @param parentNodeKey NodeKey for parent of node to be added * @param nodeKeyHashtableName String naming hashtable in which to cache key of added node * @param nodeKeyKeyPrefix int = NO_NODEKEY_KEY_PREFIX makes added node global, visible to all HTTP Sessions, * = SESSION_ID makes node UNIQUE for nodeName in session, and visible only to current session * = SESSION_ID_AND_CREATION_TIME allows multiple nodes with nodeName, and visible only to current session * @param sessionId String, ID of HTTP session calling the method * @return BonNode that was added */ private BonNode addNode(String nodeName, String nodeAttributes, String nodeContent, NodeKey nodeKey, NodeKey parentNodeKey, String nodeKeyHashtableName, int nodeKeyKeyPrefix, String sessionId) { BonNode node = new BonNode(); node.deleted = false; node.flagged = false; node.nodeName = nodeName; if(nodeAttributes != null && nodeAttributes.length() > 0) { node.nodeAttributes = “nodeKey=\””+ nodeKey + “\” “ + nodeAttributes; } else { node.nodeAttributes = “nodeKey=\””+ nodeKey + “\””; } node.nodeContent = nodeContent; node.nodeKey = nodeKey; node.parentNodeKey = parentNodeKey; // put in this ForestHashtable // also optionally put nodeKey in nodeNameHashtable // but not if it is a subject element, etc. if(nodeKeyHashtableName.equals(“nodeNameHashtable”)) { // Hashtable is synchronized, but we need to sync two together here: String nodeKeyKey = null;
  7. 588 Appendix C Source Code for bonForum Web Application synchronized(this) { try { this.put(nodeKey, node); } catch(Exception ee) { log(sessionId, “err”, “EXCEPTION in addNode():” + ee.getMessage()); ee.printStackTrace(); } if(nodeKeyKeyPrefix == SESSION_ID) { // allows only one key per session // use this option to reduce size of table // by not storing key to nodeKeys not needed // (examples: message keys, messageKey keys). nodeKeyKey = sessionId + “:” + nodeName; } else if(nodeKeyKeyPrefix == SESSION_ID_AND_CREATION_TIME) { // the nodeKey.aKey acts as a timestamp // allowing multiple keys per session in nodeNameHashtable // use to find multiple nodes with same name for one session // (example: chat keys, guest keys, host keys) nodeKeyKey = sessionId + “_” + nodeKey.aKey +”:” + nodeName; } else if(nodeKeyKeyPrefix == NO_NODEKEY_KEY_PREFIX) { // use no prefix for elements global to all sessions nodeKeyKey = nodeName; } else { nodeKeyKey = nodeName; // unknown arg value, could complain } // else ifs and/or else can add other prefixes here. // Note: it replaces older entries, if any this.nodeNameHashtable.put(nodeKeyKey, nodeKey); } } // else ifs here can add other hashtables later else { // Hashtable is synchronized, so if you change ancestor class for this, // be sure to sync addition to this here also. this.put(nodeKey, node); } return node; } /** Adds a BonNode as a root node. (Names should be unique among siblings, if nodeKeyHashtable is used)
  8. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 589 * * @param rootNodeName String naming this node * @param rootNodeAttributes String containing all attributes concatenated (name=value name=value ...) * @param rootNodeContent String containing text content of node * @param nodeKeyHashtableName String naming hashtable in which to cache key of added node * @return BonNode that was added */ protected BonNode addRootNode(String rootNodeName, String rootNodeAttributes, String rootNodeContent, String nodeKeyHashtableName) { // Node is an object that points to everything mapped to that node in the tree. // In a table that holds objects, just stick Node in table. // OTW, you can extract info and write to fields in table. NodeKey nodeKey = getNextAvailableNodeKey(); // initially, nodeKey = An.An.An; // When all three keys are equal, the row is a root node! // An empty parent node key means no parent, because it is a root node. NodeKey emptyParentNodeKey = new NodeKey(); return addNode(rootNodeName, rootNodeAttributes, rootNodeContent, nodeKey, emptyParentNodeKey, nodeKeyHashtableName, NO_NODEKEY_KEY_PREFIX, “”); } /** Adds a BonNode as a child of a root node.(Names should be unique among siblings, if nodeKeyHashtable is used) * * @param childNodeName String naming this node * @param childNodeAttributes String containing all attributes concatenated (name=value name=value ...) * @param childNodeContent String containing text content of node * @param childNodeKey NodeKey uniquely identifying a root node * @param nodeKeyHashtableName String naming hashtable in which to cache key of added node * @return BonNode that was added */ protected BonNode addChildNodeToRootNode(String childNodeName, String childNodeAttributes, String childNodeContent, NodeKey rootNodeKey, String nodeKeyHashtableName) { NodeKey childNodeKey = getNextAvailableNodeKey(); // initially, NodeKey = An.An.An; childNodeKey.bKey = rootNodeKey.aKey; childNodeKey.cKey = rootNodeKey.bKey; // when the second and third key are equal, it is child of a root return addNode(childNodeName, childNodeAttributes, childNodeContent, childNodeKey, rootNodeKey, nodeKeyHashtableName, NO_NODEKEY_KEY_PREFIX, “”); } /** Adds a BonNode as a child of a non-root node (and optionally its nodeKey to another hashtable for fast lookups).
  9. 590 Appendix C Source Code for bonForum Web Application * If “nodeNameHashtable” nodeKeyHashtable is used, sessionId must be passed in to create session-related key for nodeKey. * (for now, caller is responsible for that!) * * @param childNodeName String naming this node * @param childNodeAttributes String containing all attributes concatenated (name=value name=value ...) * @param childNodeContent String containing text content of node * @param nonRootNodeKey NodeKey uniquely identifying a non- root node * @param nodeKeyHashtableName String naming hashtable in which to cache key of added node * @param sessionId String id of callers session, if nodeKeyHashtable is used. * @return BonNode that was added */ protected BonNode addChildNodeToNonRootNode(String childNodeName, String childNodeAttributes, String childNodeContent, NodeKey nonRootNodeKey, String nodeKeyHashtableName, String sessionId) { NodeKey childNodeKey = getNextAvailableNodeKey(); // when no keys are equal, its a root grandchild or deeper childNodeKey.bKey = nonRootNodeKey.aKey; childNodeKey.cKey = nonRootNodeKey.bKey; // Assume multiple keys per nodeKey allowed in “nodeNameHashtable” nodeKeyHashtable int nodeKeyKeyPrefix = SESSION_ID_AND_CREATION_TIME; // unless node name to be added is in the “list”. if(uniqueNodeKeyKeyList.trim().length() > 0) { if(uniqueNodeKeyKeyList.indexOf(childNodeName) > -1) { nodeKeyKeyPrefix = SESSION_ID; } } return addNode(childNodeName, childNodeAttributes, childNodeContent, childNodeKey, nonRootNodeKey, nodeKeyHashtableName, nodeKeyKeyPrefix, sessionId); } /** Counts the children of a BonNode. * * @param parentNodeKey NodeKey of node whose children will be counted * @return long number of child nodes */ public long countChildren(NodeKey parentNodeKey) { // in a ForestHashtable, children have nodeKey.bKey equal to the parent’s nodeKey.aKey long counter = 0; BonNode bonNode = null; String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement();
  10. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 591 if(bonNode.nodeKey.bKey.equals(parentAKey)) { counter++; } } return counter; } /** Gets from NodeKey ArrayList the first one whose BonNode has a child with given content. * * @param nodeKeys ArrayList of NodeKeys to will be checked * @param childContent String content of child node to look for * @return NodeKey of first BonNode with child node that has childContent as content, or null */ protected NodeKey getNodeKeyByChildNameAndContent(ArrayList nodeKeys, String childName, String childContent) { Iterator iK= nodeKeys.iterator(); while(iK.hasNext()) { NodeKey nodeKey = getNodeKeyForString((String)iK.next()); NodeKey childNodeKey = getChildNodeByNameAndContent(nodeKey, childName, childContent); if(childNodeKey != null) { return nodeKey; // of parent whose child has content } } return null; } /** Gets a new NodeKey whose toString() method returns a given String. * Note: If argument string is empty or null method returns an empty NodeKey. * * @param nodeKeyString String * @return NodeKey for the given nodeKeyString */ protected NodeKey getNodeKeyForString(String nodeKeyString) { //log(sessionId, “”, “getNodeKeyForString() nodeKeyString” + nodeKeyString); NodeKey nodeKey = new NodeKey(); int inx; if((nodeKeyString == null) || (nodeKeyString.equals(“”))) { return nodeKey; } String keyString = nodeKeyString; // 984576125127.984576061235.984576061225 // 1 2 3 // 01234567890123456789012345678901234567 inx = keyString.indexOf(“.”); if(inx > -1) { nodeKey.aKey = keyString.substring(0, inx); keyString = keyString.substring(inx + 1); inx = keyString.indexOf(“.”);
  11. 592 Appendix C Source Code for bonForum Web Application if(inx > -1) { nodeKey.bKey = keyString.substring(0, inx); String cKey = keyString.substring(inx + 1); if(cKey.length() > 0) { nodeKey.cKey = cKey; } } } if(nodeKey.toString().equals(nodeKeyString)) { return nodeKey; } return null; } /** Gets ArrayList with contents of all child nodes with given name. * * @param parentNodeKey NodeKey of node whose children will be checked * @param nodeName String name of child nodes to look for * @return ArrayList of content of all child nodes with the given name */ protected ArrayList getChildNodeContentsFromName(NodeKey parentNodeKey, String nodeName) { // In a ForestHashtable, children have nodeKey.bKey equal to the parent’s nodeKey.aKey BonNode bonNode = new BonNode(); ArrayList nodeContents = new ArrayList(); if(parentNodeKey != null && nodeName != null) { String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); if(bonNode.nodeKey.bKey.equals(parentAKey)) { // it is child node if(nodeName.equals(bonNode.nodeName)) { nodeContents.add(bonNode.nodeContent.toString()); } } } return nodeContents; } return null; } /** Gets ArrayList with keys of all child nodes with given name. * * @param parentNodeKey NodeKey of node whose children will be checked * @param nodeName String name of child nodes to look for * @return ArrayList of NodeKeys of child nodes with the given name */ protected ArrayList getChildNodeKeysFromName(NodeKey parentNodeKey, String nodeName) { // In a ForestHashtable, children have nodeKey.bKey equal to the
  12. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 593 parent’s nodeKey.aKey BonNode bonNode = new BonNode(); ArrayList nodeKeys = new ArrayList(); if(parentNodeKey != null && nodeName != null) { String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); if(bonNode.nodeKey.bKey.equals(parentAKey)) { // it is child node if(nodeName.equals(bonNode.nodeName)) { nodeKeys.add(bonNode.nodeKey.toString()); } } } return nodeKeys; } return null; } /** Gets first child node with given name and/or content. * * If nodeName is null, match by content only. * If nodeContent is null, match by name only. * If both null, or no match, or no children, returns null. * * @param parentNodeKey NodeKey of node whose children will be checked * @param nodeName String child name to look for * @param nodeContent String child content to look for * @return NodeKey for first (only!) child with the given name and/or content */ protected NodeKey getChildNodeByNameAndContent(NodeKey parentNodeKey, String nodeName, String nodeContent) { // NOTE: only gets nodekey of first child with name and/or content sought! // It is used when argument value(s) must be unique among sibling nodes. // It can be easily changed to return a list of nodes instead, when needed. // In a ForestHashtable, children have nodeKey.bKey // equal to the parent’s nodeKey.aKey BonNode bonNode = new BonNode(); if(parentNodeKey != null && (nodeContent != null || nodeName != null)) { String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); if(bonNode.nodeKey.bKey.equals(parentAKey)) { // it is child node if(nodeName != null && nodeContent != null) { //
  13. 594 Appendix C Source Code for bonForum Web Application match name and content if(nodeName.equals(bonNode.nodeName)) { if(nodeContent.equals(bonNode.nodeContent)) { return bonNode.nodeKey; } } } else if(nodeName != null) { // match name only if(nodeName.equals(bonNode.nodeName)) { return bonNode.nodeKey; } } else if(nodeContent != null) { // match content only if(nodeContent.equals(bonNode.nodeContent)) { return bonNode.nodeKey; } } } } } return null; } /** Gets first child node with given attribute name and value pair. * * @param parentNodeKey NodeKey of node whose children will be checked * @param attributeName String name of attribute to look for * @param attributeValue String value of named attribute to look for * @return BonNode first child node (only!) with the given attribute name and value */ protected BonNode getChildNodeFromAttributeValue(NodeKey parentNodeKey, String attributeName, String attributeValue) { // NOTE: only gets first child with value=name sought! // It is used when attribute value must be unique among sibling nodes. // It can be easily changed to return a list of nodes instead, when needed. // In a ForestHashtable, children have nodeKey.bKey equal // to the parent’s nodeKey.aKey BonNode bonNode = new BonNode(); if(parentNodeKey != null && attributeName != null && attributeValue != null) { String parentAKey = parentNodeKey.aKey; Enumeration enumeration = this.elements(); while(enumeration.hasMoreElements()) { bonNode = (BonNode)enumeration.nextElement(); if(bonNode.nodeKey.bKey.equals(parentAKey)) { // it is child node if(attributeValue.equals(getAttributeValue(bonNode.nodeAttributes,
  14. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 595 attributeName))) { return bonNode; } } } } return null; } /** Finds out if a given attribute exists in a nodeAttributes string. * * @param allAttributes String with format used in BonNode nodeAttributes member * (No spaces allowed between attributeName and equals sign * nor between equal sign and attributeValue.) * @param attributeName String naming attribute to look for in * allAttributes * @return boolean true if given attribute exists, false otherwise */ public boolean attributeExists(String allAttributes, String attributeName) { if(allAttributes.indexOf(attributeName+”=\””) > -1) { // found name return true; } else { return false; } } /** Gets the value assigned to a given attribute in a nodeAttributes string. * * @param allAttributes String with format used in BonNode nodeAttributes member * (No spaces allowed between attributeName and equals sign * nor between equal sign and attributeValue.). * @param attributeName String naming attribute in allAttributes * whose value is returned * @return null if value has no closing quote or if attributeName not found, * else value as string. */ protected String getAttributeValue(String allAttributes, String attributeName) { String str1 = null; // type=”tes\”ti\”ng” itemKey=”961755688708.961755643923.961755643913” dateStamp=”Fri Jun 23 12:21:39 2000” int inx1 = allAttributes.indexOf(attributeName+”=\””); if(inx1 > -1) { // found name int inx2 = inx1 + (attributeName+”=\””).length();
  15. 596 Appendix C Source Code for bonForum Web Application str1 = allAttributes.substring(inx2); // remove all up through name, equals and opening quote String str2 = new String(str1); // tes\”ti\”ng” itemKey=”961755688708.961755643923.961755643913” dateStamp=”Fri Jun 23 12:21:39 2000” boolean findingClosingQuote = true; int inxAcc = 0; while(findingClosingQuote) { int inx3 = str2.indexOf(“\””); // find next quotation mark if(inx3 < 0) { str1 = null; break; } // find next escaped quotation mark (if any) int inx4 = str2.indexOf(“\\\””); if(inx4 > -1) { // found one // te\”st\”ing” goal=”961772451582” // | // inx3 // | // inx4 if(inx3 == inx4 + 1) { // same one again // accumulate an index relative to // beginning of attribute value inxAcc += inx3 + 1; // remove all up to and including escaped quote str2 = str2.substring(inx3 + 1); // ti\”ng” itemKey=”961755688708.961755643923.961755643913” dateStamp=”Fri Jun 23 12:21:39 2000” // ng” itemKey=”961755688708.961755643923.961755643913” dateStamp=”Fri Jun 23 12:21:39 2000” } else { // 961772451582” type=”te\”st\”ing” // | | // inx3 inx4 if(inxAcc > 0) { inx3 = inxAcc + ++inx3; } str1 = str1.substring(0, inx3); break; // success } } else { if(inxAcc > 0) { // ng” itemKey=”961755688708.961755643923.961755643913” dateStamp=”Fri Jun 23 12:21:39 2000”
  16. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 597 // ^ inx3 = inxAcc + ++inx3; } str1 = str1.substring(0, inx3); break; // success } } } else { log(sessionId, “err”, “ERROR in getAttributeValue()? attributeName not found!?”); } return str1; } /** Gets a BonNode given its nodeKey. * * @param nodeKey key of node to return * @return BonNode for the given key, or null if node non-existent * or nodeKey null */ protected BonNode getBonNode(NodeKey nodeKey) { if(nodeKey == null) { return null; } if(this.containsKey(nodeKey)) { return (BonNode)this.get(nodeKey); } else { return null; } } /** Allows editing name, attributes and/or content of a BonNode given its nodeKey. * Can use this for cross-HttpSession node edits, so later may have to prevent that? * If no BonNode exists for nodeKey, silently does nothing. * If all String arguments are null, silently does nothing. * * @param nodeKey NodeKey of node to edit * @param newNodeName String name of node after editing (unless null) * @param newNodeAttributes String attributes of node after * editing (unless null) * @param newNodeContent String content of node after editing (unless null) * @return NodeKey of BonNode edited, or null if no such node or * nodeKey null */ protected NodeKey editBonNode(NodeKey nodeKey, String newNodeName, String newNodeAttributes, String newNodeContent) { NodeKey retval = null;
  17. 598 Appendix C Source Code for bonForum Web Application synchronized(this) { BonNode bonNode = getBonNode(nodeKey); if(bonNode != null) { boolean putNew = false; if(newNodeName != null) { bonNode.nodeName = newNodeName; putNew = true; } if(newNodeAttributes != null) { bonNode.nodeAttributes = newNodeAttributes; putNew = true; } if(newNodeContent != null) { bonNode.nodeContent = newNodeContent; putNew = true; } if(putNew) { try { doDeleteNode(nodeKey); } catch(Exception ee) { log(sessionId, “err”, “editBonNode() EXCEPTION deleting node!:” + ee.getMessage()); } try { retval = (NodeKey)this.put(nodeKey, bonNode); } catch(Exception ee) { log(sessionId, “err”, “editBonNode() EXCEPTION putting node!:” + ee.getMessage()); } } // else silently do nothing } // else silently do nothing } return retval; } /** Gets BonNode as an XML element in a string. * * @param nodeKey NodeKey of node to edit * @return String containing an XML element, or empty if no such node */ protected String getXmlNode(NodeKey nodeKey) { String xml = “”; BonNode bonNode = getBonNode(nodeKey); if(bonNode != null) { String name = bonNode.nodeName; String attributes = bonNode.nodeAttributes; String content = bonNode.nodeContent; if (attributes != null && attributes.trim().length() > 0) { xml = xml + “
  18. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 599 else { xml = xml + “ 0) { xml = xml + “>” + content + “”; } else { xml = xml + “\\>”; } } return xml; } /** Helps with debugging only, applying getXMLNode to all elements. * * @return String containing entire ForestHashtable as XML elements */ protected String getContent() { Enumeration ee = this.elements(); String outString = “”; while(ee.hasMoreElements()) { BonNode bonNode = (BonNode)ee.nextElement(); NodeKey nodeKey = bonNode.nodeKey; outString = outString + this.getXmlNode(nodeKey); } return outString; } /** Returns a String containing all the trees in the ForestHashtable. * * NOTES: Depending on the application and its current state, * that can be a large String object! * More selectivity will be added later * for extracting XML subsets from the entire content. * This method assumes ForestHashtable includes * zero or more well-formed XML SubTrees, or, * more specifically, zero or more elements each * either a leaf node, or else the root of a * well-formed tree of elements. * * @return String containing all the trees in the ForestHashtable. */ protected String getXMLTrees() { BonNode bonNode; String xml = “”; long elementCount; String nameRootNode = “”; String nameChildOfRootNode = “”; String name = “”; String attributes = “”; String content = “”; synchronized(this) {
  19. 600 Appendix C Source Code for bonForum Web Application elementCount = unFlagAllFlaggedElements(); // unhide all hidden elements Enumeration enumerationRN = this.elements(); lastRootNodeFound = false; while (!lastRootNodeFound) { bonNode = getNextRootNode(enumerationRN); if (bonNode == null) { lastRootNodeFound = true; break; } name = bonNode.nodeName; nameRootNode = name; attributes = bonNode.nodeAttributes; content = bonNode.nodeContent; // OUTPUT A ROOTNODE if (attributes != null && attributes.trim().length() > 0) { xml = xml + “” + content; } else { xml = xml + “>”; } Enumeration enumerationCRN = this.elements(); lastChildOfRootNodeFound = false; while (!lastChildOfRootNodeFound) { bonNode = getNextChildOfRootNode(enumerationCRN); if (bonNode == null) { lastChildOfRootNodeFound = true; break; } name = bonNode.nodeName; nameChildOfRootNode = name; attributes = bonNode.nodeAttributes; content = bonNode.nodeContent; // OUTPUT A CHILD OF A ROOTNODE if (attributes != null && attributes.trim().length() > 0) { xml = xml + “” + content;
  20. C.22 Filename: Projects\bonForum\src\de\tarent\forum\ForestHashtable.java 601 } else { xml = xml + “>”; } xml = getNextChildOfNonRootNodeRecursively(xml, bonNode.nodeKey); xml = xml + “”; } xml = xml + “”; } elementCount = unFlagAllFlaggedElements(); // unhide all hidden elements } return xml; } /** Makes flagged member false for all BonNodes. * * @return long count of all BonNodes */ private long unFlagAllFlaggedElements() { Enumeration enumerationALL; BonNode bonNodeALL = null; NodeKey nodeKeyALL = null; long count = 0; boolean foundNextRootNode; foundNextRootNode = false; enumerationALL = this.elements(); while(enumerationALL.hasMoreElements()) { bonNodeALL = (BonNode)enumerationALL.nextElement(); nodeKeyALL = bonNodeALL.nodeKey; if(nodeKeyALL != null) { count++; bonNodeALL.flagged = false; // unhide each node, so we can find it } } return count; } /** Gets next root node in an enumeration of BonNode instances. * Sets its flagged member true so it will not be found again. * Keeps its nodeKey.aKey in currentRootNodeAKey, * Keeps its nodeKey.bKey in currentRootNodeBKey, * Keeps its nodeKey.cKey in currentRootNodeCKey. * * @param enumerationRN Enumeration of nodes * @return BonNode next root node in enumerationRN or null */ protected BonNode getNextRootNode(Enumeration enumerationRN) { // NOTE: This process is an extremely inefficient simulation for database model!
Đồng bộ tài khoản