Index: src/edu/ucsb/nceas/metacat/EmlSAXHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/EmlSAXHandler.java	(revision 2076)
+++ src/edu/ucsb/nceas/metacat/EmlSAXHandler.java	(revision 2077)
@@ -51,1435 +51,1374 @@
  * A database aware Class implementing callback bethods for the SAX parser to
  * call when processing the XML stream and generating events
  */
-public class EmlSAXHandler extends DBSAXHandler implements 
-                                                      AccessControlInterface
+public class EmlSAXHandler extends DBSAXHandler implements
+        AccessControlInterface
 {
-   private Vector allowRules = new Vector();
-   private Vector denyRules = new Vector();
-   private String documentId = null;
-   private Vector subDocumentIdList = new Vector();
-   private boolean processTopLeverAccess = false;
-   private boolean processAdditionalAccess = false;
-   private boolean processOtherAccess = false;
-   private AccessSection accessObject= null;
-   private AccessRule accessRule = null;
-   private Vector accessObjectList = new Vector(); // store every access rule
-   private Hashtable topLevelAccessControlMap = new Hashtable();
-   private Hashtable additionalAccessControlMap = new Hashtable();// store 
-                                                 //subtree access for single
-                                                 // additionalmetacat
-   private Vector additionalAccessMapList = new Vector();// store maps for 
-                                                       // every addionalmetadata
-   private Vector describesId = new Vector(); // store the ids in
-                                      //additionalmetadata/describes
-   private Stack subTreeInfoStack = new Stack();
-   private Vector subTreeList = new Vector();// store the final subtree
-   private Hashtable unChangableSubTreeHash = new Hashtable();
-   private Stack currentUnChangedableSubtreeNodeStack =new Stack();
-   private boolean startCriticalSubTree = false;
-   private boolean firstElementForCriticalSubTree = false;
-   private String firstElementNameForCriticalSubTree;
-   private boolean needCheckingAccessModule = false;
-   private Vector unChangableAccessSubTreeVector = new Vector();
-   private Stack currentUnchangableAccessModuleNodeStack = new Stack();
-   private AccessSection topAccessSection;
-   
-   // we need an another stack to store the access node which we pull out just
-   // from xml. If a reference happend, we can use the stack the compare nodes
-   private Stack storedAccessNodeStack = new Stack();
-   // vector stored the data file id which will be write into relation table
-   private Vector onlineDataFileIdVector = new Vector();
-   // Indicator of inline data
-   private boolean handleInlineData = false;
-   private Stack   inlineDataNodeStack = null;
-   private Hashtable inlineDataNameSpace = null;
-   private FileWriter inlineDataFileWriter = null;
-   private String inlineDataFileName = null;
-   private int inLineDataIndex = 0;
-   private Vector inlineFileIDList = new Vector();
- 
-   // Constant
-   private static final String EML ="eml";
-   private static final String DESCRIBES = "describes";
-   private static final String ADDITIONALMETADATA = "additionalMetadata";
-   private static final String ORDER = "order";
-   private static final String ID ="id";
-   private static final String REFERENCES = "references";
-   public  static final String INLINE = "inline";
-   private static final String ONLINE = "online";
-   private static final String URL    = "url";
-   private static final String PERMISSIONERROR ="User try to update a subtree"+
-                               " which it doesn't have write permission!";
-   private static final String UPDATEACCESSERROR = "User try to update a " + 
-                      "access module which it doesn't have \"ALL\" permission!";
-   private static final String TOPLEVEL = "top";
-   private static final String SUBTREELEVEL ="subtree";
-   private static final String RELATION = "Provides info for";
-  
-    /** Construct an instance of the handler class
-    * In this constructor, user can specify the version need to upadate
-    *
-    * @param conn the JDBC connection to which information is written
-    * @param action - "INSERT" or "UPDATE"
-    * @param docid to be inserted or updated into JDBC connection
-    * @param revision, the user specified the revision need to be update
-    * @param user the user connected to MetaCat servlet and owns the document
-    * @param groups the groups to which user belongs
-    * @param pub flag for public "read" access on document
-    * @param serverCode the serverid from xml_replication on which this document
-    *        resides.
-    *
-    */
-   public EmlSAXHandler(DBConnection conn, String action, String docid,
-     String revision, String user, String[] groups, String pub, int serverCode)
-                              throws SAXException
-   {
-     super(conn, action, docid, revision, user, groups, pub, serverCode);
-     // Get the unchangable subtrees (user doesn't have write permission)
-     try
-     {
-       PermissionController control = new PermissionController(docid+
-                             MetaCatUtil.getOption("accNumSeparator")+revision);
-       //unChangableSubTreeHash = getUnchangableSubTree(control, user, groups);
-       
-       
-       //If the action is update and user doesn't have "ALL" permission
-       // we need to check if user update access subtree
-       if (action.equals("UPDATE") && 
-         !control.hasPermission(user, groups, AccessControlInterface.ALLSTRING))
-       {
-         needCheckingAccessModule = true;
-         unChangableAccessSubTreeVector = getAccessSubTreeListFromDB();
-       }
-     }
-     catch (Exception e)
-     {
-       throw new SAXException(e.getMessage());
-     }
-   }
-   
-   /* Pass a permission control and get the list of unchangable subtree*/
-   private Hashtable getUnchangableSubTree(PermissionController controller,
-                                           String user, String[]groups)
-                                           throws Exception
-   {
-     Hashtable list = null;
-     Hashtable result = new Hashtable();
-     // get unwritable sutree from controller
-     list = controller.hasUnaccessableSubTree(user, groups, 
-                                          AccessControlInterface.WRITESTRING);
-      if (list != null)
-      {
-       
-         Enumeration en = list.elements();
-         while (en.hasMoreElements())
-         {
-           // Get  a subtree without node record list
-           SubTree treeWithoutStack = (SubTree)en.nextElement();
-           String subTreeId   = treeWithoutStack.getSubTreeId();
-           MetaCatUtil.debugMessage("unchangable subtree id: " + subTreeId, 40);
-           long   startNodeId = treeWithoutStack.getStartNodeId();
-           MetaCatUtil.debugMessage("unchangable subtree startnodeid: " +
-                                    startNodeId, 40);
-           long   endNodeId   = treeWithoutStack.getEndNodeId();
-           MetaCatUtil.debugMessage("unchangable subtree endnodeid: " +
-                                     endNodeId, 40);
-           // Get a subtree has the nodelist
-           SubTree tree = new SubTree(docid, subTreeId, startNodeId, endNodeId);
-           // add this tree to the result
-           result.put(subTreeId, tree);
-         
-          }//while
-      
-      }//if
-      
-      return result;
-   }
-   
-   
-   /*
-    * Get the subtree node info from xml_accesssubtree table
-    */
-   private Vector getAccessSubTreeListFromDB() throws Exception
-   {
-      Vector result = new Vector();
-      PreparedStatement pstmt = null;
-      ResultSet rs = null;
-      String sql = "SELECT controllevel, subtreeid, startnodeid, endnodeid " + 
-                   "FROM xml_accesssubtree WHERE docid like ? " +
-                   "ORDER BY startnodeid ASC";
-              
-      try 
-      {
-     
-        pstmt = connection.prepareStatement(sql);
-        // Increase DBConnection usage count
-        connection.increaseUsageCount(1);
-        // Bind the values to the query
-        pstmt.setString(1, docid);
-        pstmt.execute();
-        
-        // Get result set
-        rs = pstmt.getResultSet();
-        while (rs.next())
-        {
-          String level = rs.getString(1);
-          String sectionId = rs.getString(2);
-          long startNodeId = rs.getLong(3);
-          long endNodeId = rs.getLong(4);
-          // create a new access section
-          AccessSection accessObj = new AccessSection();
-          accessObj.setControlLevel(level);
-          accessObj.setDocId(docid);
-          accessObj.setSubTreeId(sectionId);
-          accessObj.setStartNodeId(startNodeId);
-          accessObj.setEndNodeId(endNodeId); 
-          Stack nodeStack = accessObj.getSubTreeNodeList();
-          accessObj.setSubTreeNodeStack(nodeStack);
-          // add this access obj into vector
-          result.add(accessObj);
-          // Get the top level access subtree control
-          if ( level != null && level.equals(TOPLEVEL))
-          {
-            topAccessSection = accessObj;
-          }
-        }
-        pstmt.close();
-      }//try 
-      catch (SQLException e) 
-      {
-        throw new 
-        SAXException("EMLSAXHandler.getAccessSubTreeListFromDB(): " + 
-                      e.getMessage());
-      }//catch
-      finally
-      {
-        try
-        {
-          pstmt.close();
-        }
-        catch(SQLException ee)
-        {
-          throw new 
-          SAXException("EMLSAXHandler.getAccessSubTreeListFromDB(): " + 
-          ee.getMessage());
-        }
-      }//finally
-      return result;
-   }
-   /** SAX Handler that is called at the start of each XML element */
-   public void startElement(String uri, String localName,
-                            String qName, Attributes atts)
-               throws SAXException 
-  {
-    // for element <eml:eml...> qname is "eml:eml", local name is "eml"            
-    // for element <acl....> both qname and local name is "eml"
-    // uri is namesapce
-    MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
-    MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
-    MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
-     
-     
-    DBSAXNode parentNode = null;
-    DBSAXNode currentNode = null;
-   
-   if (!handleInlineData)
-   {
-     // Get a reference to the parent node for the id
-     try 
-     {
-       parentNode = (DBSAXNode)nodeStack.peek();
-     } 
-     catch (EmptyStackException e) 
-     {
-       parentNode = null;
-     }
-     
-     //start handle inline data
-     if (localName.equals(INLINE))
-     {
-       handleInlineData = true;
-       inLineDataIndex ++;
-       //intitialize namespace hash for in line data
-       inlineDataNameSpace = new Hashtable();
-       //initialize file writer
-       String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
-       String seperator = MetaCatUtil.getOption("accNumSeparator");
-       // the new file name will look like docid.rev.2
-       inlineDataFileName = docidWithoutRev + seperator+revision+seperator +
-                         inLineDataIndex;
-       inlineDataFileWriter = createInlineDataFileWriter(inlineDataFileName);
-       // put the inline file id into a vector. If upload failed, metacat will
-       // delete the inline data file
-       inlineFileIDList.add(inlineDataFileName);
-       
-     }
-     
-     
-     // If hit a text node, we need write this text for current's parent node
-     // This will happend if the element is mixted
-     if (hitTextNode && parentNode != null)
-     {
-       //compare text node data for unchangesubtree
-       if (startCriticalSubTree)
-       {
-         compareTextNode(currentUnChangedableSubtreeNodeStack, textBuffer, 
-                         PERMISSIONERROR);
-       }//if
-      
-       //compare top level access module
-       if (processTopLeverAccess && needCheckingAccessModule)
-       {
-          compareTextNode(currentUnchangableAccessModuleNodeStack, 
-                          textBuffer, UPDATEACCESSERROR);
-       }
-       
-       if (needCheckingAccessModule && 
-       (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
-       {
-        // stored the pull out nodes into storedNode stack
-        NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT", 
-                      null, null, MetaCatUtil.normalize(textBuffer.toString()));
-        storedAccessNodeStack.push(nodeElement);
-                                         
-      }
-        
-       // write the textbuffer into db for parent node.
-        endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, parentNode);
-        // rest hitTextNode
-        hitTextNode =false;
-        // reset textbuffer
-        textBuffer = null;
-        textBuffer = new StringBuffer();
-       
-     }
-     
-  
-     // Document representation that points to the root document node
-     if (atFirstElement) 
-     {
-       atFirstElement = false;
-       // If no DOCTYPE declaration: docname = root element
-       // doctype = root element name or name space
-       if (docname == null) 
-       {
-         docname = localName;
-         // if uri isn't null doctype = uri(namespace)
-         // othewise root element
-         if (uri != null && !(uri.trim()).equals(""))
-         {
-           doctype = uri;
-         }
-         else
-         {
-           doctype = docname;
-         }
-         MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
-         MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
-       } 
-       else if (doctype == null) 
-       {
-         // because docname is not null and it is declared in dtd
-         // so could not be in schema, no namespace
-         doctype = docname;
-         MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
-       }
-       rootNode.writeNodename(docname);
-       try 
-       {
-         // for validated XML Documents store a reference to XML DB Catalog
-         // Because this is select statement and it needn't to roll back if
-         // insert document action fialed.
-         // In order to decrease DBConnection usage count, we get a new
-         // dbconnection from pool
-         String catalogid = null;
-         DBConnection dbConn = null;
-         int serialNumber = -1;
 
-        
-         try
-         {
-            // Get dbconnection
-            dbConn=DBConnectionPool.getDBConnection
-                                          ("DBSAXHandler.startElement");
-            serialNumber=dbConn.getCheckOutSerialNumber();
+    private Vector allowRules = new Vector();
 
-            Statement stmt = dbConn.createStatement();
-            ResultSet rs = stmt.executeQuery(
-                          "SELECT catalog_id FROM xml_catalog " +
-                          "WHERE entry_type = 'Schema' " +
-                          "AND public_id = '" + doctype + "'");
-            boolean hasRow = rs.next();
-            if ( hasRow ) 
-            {
-              catalogid = rs.getString(1);
-            }
-            stmt.close();
-         }//try
-         finally
-         {
-             // Return dbconnection
-             DBConnectionPool.returnDBConnection(dbConn, serialNumber);
-         }//finally
-       
+    private Vector denyRules = new Vector();
 
-         //create documentImpl object by the constructor which can specify
-         //the revision
-         currentDocument = new DocumentImpl(connection, rootNode.getNodeID(),
-                               docname, doctype, docid, revision, action, user,
-                               this.pub, catalogid, this.serverCode);
+    private String documentId = null;
 
+    private Vector subDocumentIdList = new Vector();
 
-       } 
-       catch (Exception ane) 
-       {
-         throw (new SAXException("Error in EMLSaxHandler.startElement " +
-                                 action, ane));
-       }
-     }
+    private boolean processTopLeverAccess = false;
 
-     // Create the current node representation
-     currentNode = new DBSAXNode(connection, qName, localName, parentNode,
-                                 currentDocument.getRootNodeID(),docid,
-                                 currentDocument.getDoctype());
-     // Use a local variable to store the element node id
-     // If this element is a start point of subtree(section), it will be stored
-     // otherwise, it will be discated
-     long startNodeId = currentNode.getNodeID();
-     // Add all of the namespaces
-     String prefix =null;
-     String nsuri = null;
-     Enumeration prefixes = namespaces.keys();
-     while ( prefixes.hasMoreElements() ) 
-     {
-       prefix = (String)prefixes.nextElement();
-       nsuri = (String)namespaces.get(prefix);
-       endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
-     }
-   
+    private boolean processAdditionalAccess = false;
 
-     // Add all of the attributes
-     for (int i=0; i<atts.getLength(); i++) 
-     {
-       String attributeName = atts.getQName(i);
-       String attributeValue = atts.getValue(i);
-       endNodeId = 
-                currentNode.setAttribute(attributeName, attributeValue, docid);
-       
-       // To handle name space and schema location if the attribute name is
-       // xsi:schemaLocation. If the name space is in not in catalog table
-       // it will be regeistered.
-       if (attributeName != null && 
-           attributeName.indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1)
-       {
-         SchemaLocationResolver resolver = 
-                                  new SchemaLocationResolver(attributeValue);
-         resolver.resolveNameSpace();
-         
-       }
-       else if (attributeName !=null && attributeName.equals(ID))
-       {
-        
-        
-         //check unchangedable subtree hash if contains this subtree id
-         if (unChangableSubTreeHash.containsKey(attributeValue))
-         {
-           // this subtree couldn't be changed by the user and move it from hash
-           SubTree currentUnChangedableSubtree = (SubTree)
-                                  unChangableSubTreeHash.remove(attributeValue);
-           currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree.
-                                                         getSubTreeNodeStack();
-           startCriticalSubTree = true;
-           firstElementForCriticalSubTree = true;
-         }
-         
-         // handle subtree info
-         SubTree subTress = new SubTree();
-         // set sub tree id
-         subTress.setSubTreeId(attributeValue);
-         // set sub tree sstart lement name
-         subTress.setStartElementName(currentNode.getTagName());
-         // set start node number
-         subTress.setStartNodeId(startNodeId);
-         // add to stack, but it didn't get end node id yet
-         subTreeInfoStack.push(subTress);
-         
-       }
-     }//for
-   
-     // handle access stuff
-     if (localName.equals(ACCESS))
-     {
-       // if it is in addtionalmetacat
-       if (parentNode.getTagName() == ADDITIONALMETADATA)
-       {
-         processAdditionalAccess = true;
-        
-       }
-       else
-       {
-         //make sure the access is top level
-         // this mean current node's parent's parent should be "eml"
-         DBSAXNode tmpNode = (DBSAXNode) nodeStack.pop();// pop out parent node
-         //peek out grandParentNode
-         DBSAXNode grandParentNode = (DBSAXNode)nodeStack.peek();
-         // put parent node back
-         nodeStack.push(tmpNode);
-         String grandParentTag = grandParentNode.getTagName();
-         if (grandParentTag.equals(EML))
-         {
-           processTopLeverAccess = true;
-         }
-         else
-         {
-           // process other access embedded into resource level module
-           processOtherAccess = true;
-         }
-        
-       }
-       // create access object 
-       accessObject = new AccessSection();
-         // set permission order
-       String permOrder = currentNode.getAttribute(ORDER);
-       accessObject.setPermissionOrder(permOrder);
-       // set access id
-       String accessId = currentNode.getAttribute(ID);
-       accessObject.setSubTreeId(accessId);
-       accessObject.setStartNodeId(startNodeId);
-       accessObject.setDocId(docid);
-       
-       // load top level node stack to currentUnchangableAccessModuleNodeStack
-       if (processTopLeverAccess && needCheckingAccessModule)
-       {
-         // get the node stack for
-         currentUnchangableAccessModuleNodeStack = 
-                                        topAccessSection.getSubTreeNodeStack();
-       }
-                 
-       
-     }
-     // Set up a access rule for allow
-     else if (parentNode.getTagName() != null && 
-       (parentNode.getTagName()).equals(ACCESS) && localName.equals(ALLOW))
-     {
-      
-       accessRule = new AccessRule(); 
-      
-       //set permission type "allow"
-       accessRule.setPermissionType(ALLOW);
-      
-     }
-     // set up an access rule for den
-     else if (parentNode.getTagName() != null 
-       && (parentNode.getTagName()).equals(ACCESS) && localName.equals(DENY))
-     {
-       accessRule = new AccessRule();
-       //set permission type "allow"
-       accessRule.setPermissionType(DENY);
-     }
-      
-     // Add the node to the stack, so that any text data can be
-     // added as it is encountered
-     nodeStack.push(currentNode);
-     // Add the node to the vector used by thread for writing XML Index
-     nodeIndex.addElement(currentNode);
-    
-    // handle critical subtree
-    if (startCriticalSubTree && firstElementForCriticalSubTree)
+    private boolean processOtherAccess = false;
+
+    private AccessSection accessObject = null;
+
+    private AccessRule accessRule = null;
+
+    private Vector accessObjectList = new Vector(); // store every access rule
+
+    private Hashtable topLevelAccessControlMap = new Hashtable();
+
+    private Hashtable additionalAccessControlMap = new Hashtable();// store
+
+    //subtree access for single
+    // additionalmetacat
+    private Vector additionalAccessMapList = new Vector();// store maps for
+
+    // every addionalmetadata
+    private Vector describesId = new Vector(); // store the ids in
+
+    //additionalmetadata/describes
+    private Stack subTreeInfoStack = new Stack();
+
+    private Vector subTreeList = new Vector();// store the final subtree
+
+    private Hashtable unChangableSubTreeHash = new Hashtable();
+
+    private Stack currentUnChangedableSubtreeNodeStack = new Stack();
+
+    private boolean startCriticalSubTree = false;
+
+    private boolean firstElementForCriticalSubTree = false;
+
+    private String firstElementNameForCriticalSubTree;
+
+    private boolean needCheckingAccessModule = false;
+
+    private Vector unChangableAccessSubTreeVector = new Vector();
+
+    private Stack currentUnchangableAccessModuleNodeStack = new Stack();
+
+    private AccessSection topAccessSection;
+
+    // we need an another stack to store the access node which we pull out just
+    // from xml. If a reference happend, we can use the stack the compare nodes
+    private Stack storedAccessNodeStack = new Stack();
+
+    // vector stored the data file id which will be write into relation table
+    private Vector onlineDataFileIdVector = new Vector();
+
+    // Indicator of inline data
+    private boolean handleInlineData = false;
+
+    private Stack inlineDataNodeStack = null;
+
+    private Hashtable inlineDataNameSpace = null;
+
+    private FileWriter inlineDataFileWriter = null;
+
+    private String inlineDataFileName = null;
+
+    private int inLineDataIndex = 0;
+
+    private Vector inlineFileIDList = new Vector();
+
+    // Constant
+    private static final String EML = "eml";
+
+    private static final String DESCRIBES = "describes";
+
+    private static final String ADDITIONALMETADATA = "additionalMetadata";
+
+    private static final String ORDER = "order";
+
+    private static final String ID = "id";
+
+    private static final String REFERENCES = "references";
+
+    public static final String INLINE = "inline";
+
+    private static final String ONLINE = "online";
+
+    private static final String URL = "url";
+
+    private static final String PERMISSIONERROR = "User try to update a subtree"
+            + " which it doesn't have write permission!";
+
+    private static final String UPDATEACCESSERROR = "User try to update a "
+            + "access module which it doesn't have \"ALL\" permission!";
+
+    private static final String TOPLEVEL = "top";
+
+    private static final String SUBTREELEVEL = "subtree";
+
+    private static final String RELATION = "Provides info for";
+
+    /**
+     * Construct an instance of the handler class In this constructor, user can
+     * specify the version need to upadate
+     * 
+     * @param conn the JDBC connection to which information is written
+     * @param action - "INSERT" or "UPDATE"
+     * @param docid to be inserted or updated into JDBC connection
+     * @param revision, the user specified the revision need to be update
+     * @param user the user connected to MetaCat servlet and owns the document
+     * @param groups the groups to which user belongs
+     * @param pub flag for public "read" access on document
+     * @param serverCode the serverid from xml_replication on which this
+     *            document resides.
+     *  
+     */
+    public EmlSAXHandler(DBConnection conn, String action, String docid,
+            String revision, String user, String[] groups, String pub,
+            int serverCode) throws SAXException
     {
-      //store the element name
-      firstElementNameForCriticalSubTree = qName;
-      firstElementForCriticalSubTree = false;
-    }//for first element
-    
-    // handle critical subtree
-    if (startCriticalSubTree)
+        super(conn, action, docid, revision, user, groups, pub, serverCode);
+        // Get the unchangable subtrees (user doesn't have write permission)
+        try {
+            PermissionController control = new PermissionController(docid
+                    + MetaCatUtil.getOption("accNumSeparator") + revision);
+            //unChangableSubTreeHash = getUnchangableSubTree(control, user,
+            // groups);
+
+            //If the action is update and user doesn't have "ALL" permission
+            // we need to check if user update access subtree
+            if (action.equals("UPDATE")
+                    && !control.hasPermission(user, groups,
+                            AccessControlInterface.ALLSTRING)) {
+                needCheckingAccessModule = true;
+                unChangableAccessSubTreeVector = getAccessSubTreeListFromDB();
+            }
+        } catch (Exception e) {
+            throw new SAXException(e.getMessage());
+        }
+    }
+
+    /* Pass a permission control and get the list of unchangable subtree */
+    private Hashtable getUnchangableSubTree(PermissionController controller,
+            String user, String[] groups) throws Exception
     {
-      compareElementNameSpaceAttributes(currentUnChangedableSubtreeNodeStack,
-                                        namespaces, atts, localName, 
-                                        PERMISSIONERROR);
-      
+        Hashtable list = null;
+        Hashtable result = new Hashtable();
+        // get unwritable sutree from controller
+        list = controller.hasUnaccessableSubTree(user, groups,
+                AccessControlInterface.WRITESTRING);
+        if (list != null) {
+
+            Enumeration en = list.elements();
+            while (en.hasMoreElements()) {
+                // Get a subtree without node record list
+                SubTree treeWithoutStack = (SubTree) en.nextElement();
+                String subTreeId = treeWithoutStack.getSubTreeId();
+                MetaCatUtil.debugMessage(
+                        "unchangable subtree id: " + subTreeId, 40);
+                long startNodeId = treeWithoutStack.getStartNodeId();
+                MetaCatUtil.debugMessage("unchangable subtree startnodeid: "
+                        + startNodeId, 40);
+                long endNodeId = treeWithoutStack.getEndNodeId();
+                MetaCatUtil.debugMessage("unchangable subtree endnodeid: "
+                        + endNodeId, 40);
+                // Get a subtree has the nodelist
+                SubTree tree = new SubTree(docid, subTreeId, startNodeId,
+                        endNodeId);
+                // add this tree to the result
+                result.put(subTreeId, tree);
+
+            }//while
+
+        }//if
+
+        return result;
     }
-    //compare top access level module
-    if (processTopLeverAccess && needCheckingAccessModule)
+
+    /*
+     * Get the subtree node info from xml_accesssubtree table
+     */
+    private Vector getAccessSubTreeListFromDB() throws Exception
     {
-      compareElementNameSpaceAttributes(currentUnchangableAccessModuleNodeStack, 
-                                        namespaces, atts, localName, 
-                                        UPDATEACCESSERROR);
-       
+        Vector result = new Vector();
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        String sql = "SELECT controllevel, subtreeid, startnodeid, endnodeid "
+                + "FROM xml_accesssubtree WHERE docid like ? "
+                + "ORDER BY startnodeid ASC";
+
+        try {
+
+            pstmt = connection.prepareStatement(sql);
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            // Bind the values to the query
+            pstmt.setString(1, docid);
+            pstmt.execute();
+
+            // Get result set
+            rs = pstmt.getResultSet();
+            while (rs.next()) {
+                String level = rs.getString(1);
+                String sectionId = rs.getString(2);
+                long startNodeId = rs.getLong(3);
+                long endNodeId = rs.getLong(4);
+                // create a new access section
+                AccessSection accessObj = new AccessSection();
+                accessObj.setControlLevel(level);
+                accessObj.setDocId(docid);
+                accessObj.setSubTreeId(sectionId);
+                accessObj.setStartNodeId(startNodeId);
+                accessObj.setEndNodeId(endNodeId);
+                Stack nodeStack = accessObj.getSubTreeNodeList();
+                accessObj.setSubTreeNodeStack(nodeStack);
+                // add this access obj into vector
+                result.add(accessObj);
+                // Get the top level access subtree control
+                if (level != null && level.equals(TOPLEVEL)) {
+                    topAccessSection = accessObj;
+                }
+            }
+            pstmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException(
+                    "EMLSAXHandler.getAccessSubTreeListFromDB(): "
+                            + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pstmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException(
+                        "EMLSAXHandler.getAccessSubTreeListFromDB(): "
+                                + ee.getMessage());
+            }
+        }//finally
+        return result;
     }
-    
-    // store access module element and attributes into stored stack
-    if (needCheckingAccessModule && 
-       (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
+
+    /** SAX Handler that is called at the start of each XML element */
+    public void startElement(String uri, String localName, String qName,
+            Attributes atts) throws SAXException
     {
-       // stored the pull out nodes into storedNode stack
-       NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "ELEMENT", 
-                                localName, prefix, MetaCatUtil.normalize(null));
-       storedAccessNodeStack.push(nodeElement);
-       for (int i=0; i<atts.getLength(); i++) 
-       {
-         String attributeName = atts.getQName(i);
-         String attributeValue = atts.getValue(i);
-         NodeRecord nodeAttribute = new NodeRecord(-2, -2, -2, "ATTRIBUTE",
-                    attributeName, null, MetaCatUtil.normalize(attributeValue));
-         storedAccessNodeStack.push(nodeAttribute);
-       }
-                                   
+        // for element <eml:eml...> qname is "eml:eml", local name is "eml"
+        // for element <acl....> both qname and local name is "eml"
+        // uri is namesapce
+        MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
+        MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
+        MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
+
+        DBSAXNode parentNode = null;
+        DBSAXNode currentNode = null;
+
+        if (!handleInlineData) {
+            // Get a reference to the parent node for the id
+            try {
+                parentNode = (DBSAXNode) nodeStack.peek();
+            } catch (EmptyStackException e) {
+                parentNode = null;
+            }
+
+            //start handle inline data
+            if (localName.equals(INLINE)) {
+                handleInlineData = true;
+                inLineDataIndex++;
+                //intitialize namespace hash for in line data
+                inlineDataNameSpace = new Hashtable();
+                //initialize file writer
+                String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
+                String seperator = MetaCatUtil.getOption("accNumSeparator");
+                // the new file name will look like docid.rev.2
+                inlineDataFileName = docidWithoutRev + seperator + revision
+                        + seperator + inLineDataIndex;
+                inlineDataFileWriter = createInlineDataFileWriter(inlineDataFileName);
+                // put the inline file id into a vector. If upload failed,
+                // metacat will
+                // delete the inline data file
+                inlineFileIDList.add(inlineDataFileName);
+
+            }
+
+            // If hit a text node, we need write this text for current's parent
+            // node
+            // This will happend if the element is mixted
+            if (hitTextNode && parentNode != null) {
+                //compare text node data for unchangesubtree
+                if (startCriticalSubTree) {
+                    compareTextNode(currentUnChangedableSubtreeNodeStack,
+                            textBuffer, PERMISSIONERROR);
+                }//if
+
+                //compare top level access module
+                if (processTopLeverAccess && needCheckingAccessModule) {
+                    compareTextNode(currentUnchangableAccessModuleNodeStack,
+                            textBuffer, UPDATEACCESSERROR);
+                }
+
+                if (needCheckingAccessModule
+                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
+                    // stored the pull out nodes into storedNode stack
+                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT",
+                            null, null, MetaCatUtil.normalize(textBuffer
+                                    .toString()));
+                    storedAccessNodeStack.push(nodeElement);
+
+                }
+
+                // write the textbuffer into db for parent node.
+                endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
+                        parentNode);
+                // rest hitTextNode
+                hitTextNode = false;
+                // reset textbuffer
+                textBuffer = null;
+                textBuffer = new StringBuffer();
+
+            }
+
+            // Document representation that points to the root document node
+            if (atFirstElement) {
+                atFirstElement = false;
+                // If no DOCTYPE declaration: docname = root element
+                // doctype = root element name or name space
+                if (docname == null) {
+                    docname = localName;
+                    // if uri isn't null doctype = uri(namespace)
+                    // othewise root element
+                    if (uri != null && !(uri.trim()).equals("")) {
+                        doctype = uri;
+                    } else {
+                        doctype = docname;
+                    }
+                    MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
+                    MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
+                } else if (doctype == null) {
+                    // because docname is not null and it is declared in dtd
+                    // so could not be in schema, no namespace
+                    doctype = docname;
+                    MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
+                }
+                rootNode.writeNodename(docname);
+                try {
+                    // for validated XML Documents store a reference to XML DB
+                    // Catalog
+                    // Because this is select statement and it needn't to roll
+                    // back if
+                    // insert document action fialed.
+                    // In order to decrease DBConnection usage count, we get a
+                    // new
+                    // dbconnection from pool
+                    String catalogid = null;
+                    DBConnection dbConn = null;
+                    int serialNumber = -1;
+
+                    try {
+                        // Get dbconnection
+                        dbConn = DBConnectionPool
+                                .getDBConnection("DBSAXHandler.startElement");
+                        serialNumber = dbConn.getCheckOutSerialNumber();
+
+                        Statement stmt = dbConn.createStatement();
+                        ResultSet rs = stmt
+                                .executeQuery("SELECT catalog_id FROM xml_catalog "
+                                        + "WHERE entry_type = 'Schema' "
+                                        + "AND public_id = '" + doctype + "'");
+                        boolean hasRow = rs.next();
+                        if (hasRow) {
+                            catalogid = rs.getString(1);
+                        }
+                        stmt.close();
+                    }//try
+                    finally {
+                        // Return dbconnection
+                        DBConnectionPool.returnDBConnection(dbConn,
+                                serialNumber);
+                    }//finally
+
+                    //create documentImpl object by the constructor which can
+                    // specify
+                    //the revision
+                    currentDocument = new DocumentImpl(connection, rootNode
+                            .getNodeID(), docname, doctype, docid, revision,
+                            action, user, this.pub, catalogid, this.serverCode);
+
+                } catch (Exception ane) {
+                    throw (new SAXException(
+                            "Error in EMLSaxHandler.startElement " + action,
+                            ane));
+                }
+            }
+
+            // Create the current node representation
+            currentNode = new DBSAXNode(connection, qName, localName,
+                    parentNode, currentDocument.getRootNodeID(), docid,
+                    currentDocument.getDoctype());
+            // Use a local variable to store the element node id
+            // If this element is a start point of subtree(section), it will be
+            // stored
+            // otherwise, it will be discated
+            long startNodeId = currentNode.getNodeID();
+            // Add all of the namespaces
+            String prefix = null;
+            String nsuri = null;
+            Enumeration prefixes = namespaces.keys();
+            while (prefixes.hasMoreElements()) {
+                prefix = (String) prefixes.nextElement();
+                nsuri = (String) namespaces.get(prefix);
+                endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
+            }
+
+            // Add all of the attributes
+            for (int i = 0; i < atts.getLength(); i++) {
+                String attributeName = atts.getQName(i);
+                String attributeValue = atts.getValue(i);
+                endNodeId = currentNode.setAttribute(attributeName,
+                        attributeValue, docid);
+
+                // To handle name space and schema location if the attribute
+                // name is
+                // xsi:schemaLocation. If the name space is in not in catalog
+                // table
+                // it will be regeistered.
+                if (attributeName != null
+                        && attributeName
+                                .indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1) {
+                    SchemaLocationResolver resolver = new SchemaLocationResolver(
+                            attributeValue);
+                    resolver.resolveNameSpace();
+
+                } else if (attributeName != null && attributeName.equals(ID)) {
+
+                    //check unchangedable subtree hash if contains this
+                    // subtree id
+                    if (unChangableSubTreeHash.containsKey(attributeValue)) {
+                        // this subtree couldn't be changed by the user and
+                        // move it from hash
+                        SubTree currentUnChangedableSubtree = (SubTree) unChangableSubTreeHash
+                                .remove(attributeValue);
+                        currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree
+                                .getSubTreeNodeStack();
+                        startCriticalSubTree = true;
+                        firstElementForCriticalSubTree = true;
+                    }
+
+                    // handle subtree info
+                    SubTree subTress = new SubTree();
+                    // set sub tree id
+                    subTress.setSubTreeId(attributeValue);
+                    // set sub tree sstart lement name
+                    subTress.setStartElementName(currentNode.getTagName());
+                    // set start node number
+                    subTress.setStartNodeId(startNodeId);
+                    // add to stack, but it didn't get end node id yet
+                    subTreeInfoStack.push(subTress);
+
+                }
+            }//for
+
+            // handle access stuff
+            if (localName.equals(ACCESS)) {
+                // if it is in addtionalmetacat
+                if (parentNode.getTagName() == ADDITIONALMETADATA) {
+                    processAdditionalAccess = true;
+
+                } else {
+                    //make sure the access is top level
+                    // this mean current node's parent's parent should be "eml"
+                    DBSAXNode tmpNode = (DBSAXNode) nodeStack.pop();// pop out
+                                                                    // parent
+                                                                    // node
+                    //peek out grandParentNode
+                    DBSAXNode grandParentNode = (DBSAXNode) nodeStack.peek();
+                    // put parent node back
+                    nodeStack.push(tmpNode);
+                    String grandParentTag = grandParentNode.getTagName();
+                    if (grandParentTag.equals(EML)) {
+                        processTopLeverAccess = true;
+                    } else {
+                        // process other access embedded into resource level
+                        // module
+                        processOtherAccess = true;
+                    }
+
+                }
+                // create access object
+                accessObject = new AccessSection();
+                // set permission order
+                String permOrder = currentNode.getAttribute(ORDER);
+                accessObject.setPermissionOrder(permOrder);
+                // set access id
+                String accessId = currentNode.getAttribute(ID);
+                accessObject.setSubTreeId(accessId);
+                accessObject.setStartNodeId(startNodeId);
+                accessObject.setDocId(docid);
+
+                // load top level node stack to
+                // currentUnchangableAccessModuleNodeStack
+                if (processTopLeverAccess && needCheckingAccessModule) {
+                    // get the node stack for
+                    currentUnchangableAccessModuleNodeStack = topAccessSection
+                            .getSubTreeNodeStack();
+                }
+
+            }
+            // Set up a access rule for allow
+            else if (parentNode.getTagName() != null
+                    && (parentNode.getTagName()).equals(ACCESS)
+                    && localName.equals(ALLOW)) {
+
+                accessRule = new AccessRule();
+
+                //set permission type "allow"
+                accessRule.setPermissionType(ALLOW);
+
+            }
+            // set up an access rule for den
+            else if (parentNode.getTagName() != null
+                    && (parentNode.getTagName()).equals(ACCESS)
+                    && localName.equals(DENY)) {
+                accessRule = new AccessRule();
+                //set permission type "allow"
+                accessRule.setPermissionType(DENY);
+            }
+
+            // Add the node to the stack, so that any text data can be
+            // added as it is encountered
+            nodeStack.push(currentNode);
+            // Add the node to the vector used by thread for writing XML Index
+            nodeIndex.addElement(currentNode);
+
+            // handle critical subtree
+            if (startCriticalSubTree && firstElementForCriticalSubTree) {
+                //store the element name
+                firstElementNameForCriticalSubTree = qName;
+                firstElementForCriticalSubTree = false;
+            }//for first element
+
+            // handle critical subtree
+            if (startCriticalSubTree) {
+                compareElementNameSpaceAttributes(
+                        currentUnChangedableSubtreeNodeStack, namespaces, atts,
+                        localName, PERMISSIONERROR);
+
+            }
+            //compare top access level module
+            if (processTopLeverAccess && needCheckingAccessModule) {
+                compareElementNameSpaceAttributes(
+                        currentUnchangableAccessModuleNodeStack, namespaces,
+                        atts, localName, UPDATEACCESSERROR);
+
+            }
+
+            // store access module element and attributes into stored stack
+            if (needCheckingAccessModule
+                    && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
+                // stored the pull out nodes into storedNode stack
+                NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "ELEMENT",
+                        localName, prefix, MetaCatUtil.normalize(null));
+                storedAccessNodeStack.push(nodeElement);
+                for (int i = 0; i < atts.getLength(); i++) {
+                    String attributeName = atts.getQName(i);
+                    String attributeValue = atts.getValue(i);
+                    NodeRecord nodeAttribute = new NodeRecord(-2, -2, -2,
+                            "ATTRIBUTE", attributeName, null, MetaCatUtil
+                                    .normalize(attributeValue));
+                    storedAccessNodeStack.push(nodeAttribute);
+                }
+
+            }
+
+            // reset name space
+            namespaces = null;
+            namespaces = new Hashtable();
+        }//not inline data
+        else {
+            // we don't buffer the inline data in characters() method
+            // so start character don't need to hand text node.
+
+            // inline data may be the xml format.
+            StringBuffer inlineElements = new StringBuffer();
+            inlineElements.append("<").append(qName);
+            // append attributes
+            for (int i = 0; i < atts.getLength(); i++) {
+                String attributeName = atts.getQName(i);
+                String attributeValue = atts.getValue(i);
+                inlineElements.append(" ");
+                inlineElements.append(attributeName);
+                inlineElements.append("=\"");
+                inlineElements.append(attributeValue);
+                inlineElements.append("\"");
+            }
+            // append namespace
+            String prefix = null;
+            String nsuri = null;
+            Enumeration prefixes = inlineDataNameSpace.keys();
+            while (prefixes.hasMoreElements()) {
+                prefix = (String) prefixes.nextElement();
+                nsuri = (String) namespaces.get(prefix);
+                inlineElements.append(" ");
+                inlineElements.append("xmlns:");
+                inlineElements.append(prefix);
+                inlineElements.append("=\"");
+                inlineElements.append(nsuri);
+                inlineElements.append("\"");
+            }
+            inlineElements.append(">");
+            //reset inline data name space
+            inlineDataNameSpace = null;
+            inlineDataNameSpace = new Hashtable();
+            //write inline data into file
+            MetaCatUtil.debugMessage("the inline element data is: "
+                    + inlineElements.toString(), 50);
+            writeInlineDataIntoFile(inlineDataFileWriter, inlineElements);
+        }//else
+
     }
-   
-    // reset name space
-    namespaces = null;
-    namespaces = new Hashtable();
-   }//not inline data
-   else
-   {
-       // we don't buffer the inline data in characters() method
-       // so start character don't need to hand text node.
-       
-       // inline data may be the xml format.
-       StringBuffer inlineElements = new StringBuffer();
-       inlineElements.append("<").append(qName);
-       // append attributes
-       for (int i=0; i<atts.getLength(); i++) 
-       {
-         String attributeName = atts.getQName(i);
-         String attributeValue = atts.getValue(i);
-         inlineElements.append(" ");
-         inlineElements.append(attributeName);
-         inlineElements.append("=\"");
-         inlineElements.append(attributeValue);
-         inlineElements.append("\"");
-       }
-       // append namespace
-       String prefix =null;
-       String nsuri = null;
-       Enumeration prefixes = inlineDataNameSpace.keys();
-       while ( prefixes.hasMoreElements() ) 
-       {
-         prefix = (String)prefixes.nextElement();
-         nsuri = (String)namespaces.get(prefix);
-         inlineElements.append(" ");
-         inlineElements.append("xmlns:");
-         inlineElements.append(prefix);
-         inlineElements.append("=\"");
-         inlineElements.append(nsuri);
-         inlineElements.append("\"");
-       }
-       inlineElements.append(">");
-       //reset inline data name space
-       inlineDataNameSpace = null;
-       inlineDataNameSpace = new Hashtable();
-       //write inline data into file
-       MetaCatUtil.debugMessage("the inline element data is: "+ 
-                                 inlineElements.toString(), 50);
-       writeInlineDataIntoFile(inlineDataFileWriter, inlineElements);
-   }//else
-   
-  }
-  
-  private void compareElementNameSpaceAttributes(Stack unchangableNodeStack, 
-                                            Hashtable nameSpaces,
-                                            Attributes attributes,
-                                            String localName, String error) 
-                                            throws SAXException
-  {
-     //Get element subtree node stack (element node)
-      NodeRecord elementNode = null;
-      try
-      {
-        elementNode= (NodeRecord) unchangableNodeStack.pop();
-      }
-      catch (EmptyStackException ee)
-      {
-        MetaCatUtil.debugMessage("Node stack is empty for element data", 35);
-        throw new SAXException(error);
-      }
-      MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
-      MetaCatUtil.debugMessage("node type from stack: " + 
-                                  elementNode.getNodeType(), 40);
-      MetaCatUtil.debugMessage("node name from xml document: " + 
-                                  localName, 40);
-      MetaCatUtil.debugMessage("node name from stack: " +
-                                  elementNode.getNodeName(), 40);
-      MetaCatUtil.debugMessage("node data from stack: " +
-                                  elementNode.getNodeData(), 40);
-      MetaCatUtil.debugMessage("node id is: "+ elementNode.getNodeId(), 40);
-      // if this node is not element or local name not equal or name space not
-      // equals, throw an exception
-      if (!elementNode.getNodeType().equals("ELEMENT") || 
-          !localName.equals(elementNode.getNodeName()))
+
+    private void compareElementNameSpaceAttributes(Stack unchangableNodeStack,
+            Hashtable nameSpaces, Attributes attributes, String localName,
+            String error) throws SAXException
+    {
+        //Get element subtree node stack (element node)
+        NodeRecord elementNode = null;
+        try {
+            elementNode = (NodeRecord) unchangableNodeStack.pop();
+        } catch (EmptyStackException ee) {
+            MetaCatUtil
+                    .debugMessage("Node stack is empty for element data", 35);
+            throw new SAXException(error);
+        }
+        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
+        MetaCatUtil.debugMessage("node type from stack: "
+                + elementNode.getNodeType(), 40);
+        MetaCatUtil.debugMessage("node name from xml document: " + localName,
+                40);
+        MetaCatUtil.debugMessage("node name from stack: "
+                + elementNode.getNodeName(), 40);
+        MetaCatUtil.debugMessage("node data from stack: "
+                + elementNode.getNodeData(), 40);
+        MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(), 40);
+        // if this node is not element or local name not equal or name space
+        // not
+        // equals, throw an exception
+        if (!elementNode.getNodeType().equals("ELEMENT")
+                || !localName.equals(elementNode.getNodeName()))
         //  (uri != null && !uri.equals(elementNode.getNodePrefix())))
-      {
-        MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
-        MetaCatUtil.debugMessage("node type from stack: " + 
-                                  elementNode.getNodeType(), 40);
-        MetaCatUtil.debugMessage("node name from xml document: " + 
-                                  localName, 40);
-        MetaCatUtil.debugMessage("node name from stack: " +
-                                  elementNode.getNodeName(), 40);
-        MetaCatUtil.debugMessage("node data from stack: " +
-                                  elementNode.getNodeData(), 40);
-        MetaCatUtil.debugMessage("node id is: "+ elementNode.getNodeId(), 40);
-        throw new SAXException(error);
-      }
-      
-      //compare namespace
-     Enumeration nameEn = nameSpaces.keys();
-     while ( nameEn.hasMoreElements() ) 
-     {
-       //Get namespacke node stack (element node)
-       NodeRecord nameNode = null;
-       try
-       { 
-         nameNode = (NodeRecord) unchangableNodeStack.pop();
-       }
-       catch (EmptyStackException ee)
-       {
-         MetaCatUtil.debugMessage("Node stack is empty for namespace data", 35);
-         throw new SAXException(error);
-       }
-       
-       String prefixName = (String)nameEn.nextElement(); 
-       String nameSpaceUri = (String)nameSpaces.get(prefixName);
-       if (!nameNode.getNodeType().equals("NAMESPACE") || 
-           !prefixName.equals(nameNode.getNodeName()) || 
-           !nameSpaceUri.equals(nameNode.getNodeData()))
-       { 
-         MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-         MetaCatUtil.debugMessage("current node type from xml is NAMESPACE", 40);
-         MetaCatUtil.debugMessage("node type from stack: " + 
-                                  nameNode.getNodeType(), 40);
-         MetaCatUtil.debugMessage("current node name from xml is: " + 
-                                   prefixName, 40);
-         MetaCatUtil.debugMessage("node name from stack: " +
-                                  nameNode.getNodeName(), 40);
-         MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                   nameSpaceUri, 40);
-         MetaCatUtil.debugMessage("node data from stack: " +
-                                  nameNode.getNodeData(), 40);
-         MetaCatUtil.debugMessage("node id is: "+ nameNode.getNodeId(), 40);
-         throw new SAXException(error);
-       }
-      
-     }//while
-      
-      //compare attributes
-      for (int i=0; i<attributes.getLength(); i++)
-      {
-        NodeRecord attriNode = null;
-        try
         {
-          attriNode = (NodeRecord)unchangableNodeStack.pop();
-          
+            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+            MetaCatUtil.debugMessage("current node type from xml is ELEMENT",
+                    40);
+            MetaCatUtil.debugMessage("node type from stack: "
+                    + elementNode.getNodeType(), 40);
+            MetaCatUtil.debugMessage("node name from xml document: "
+                    + localName, 40);
+            MetaCatUtil.debugMessage("node name from stack: "
+                    + elementNode.getNodeName(), 40);
+            MetaCatUtil.debugMessage("node data from stack: "
+                    + elementNode.getNodeData(), 40);
+            MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(),
+                    40);
+            throw new SAXException(error);
         }
-        catch (EmptyStackException ee)
-        {
-          MetaCatUtil.debugMessage("Node stack is empty for attribute data", 35);
-          throw new SAXException(error);
+
+        //compare namespace
+        Enumeration nameEn = nameSpaces.keys();
+        while (nameEn.hasMoreElements()) {
+            //Get namespacke node stack (element node)
+            NodeRecord nameNode = null;
+            try {
+                nameNode = (NodeRecord) unchangableNodeStack.pop();
+            } catch (EmptyStackException ee) {
+                MetaCatUtil.debugMessage(
+                        "Node stack is empty for namespace data", 35);
+                throw new SAXException(error);
+            }
+
+            String prefixName = (String) nameEn.nextElement();
+            String nameSpaceUri = (String) nameSpaces.get(prefixName);
+            if (!nameNode.getNodeType().equals("NAMESPACE")
+                    || !prefixName.equals(nameNode.getNodeName())
+                    || !nameSpaceUri.equals(nameNode.getNodeData())) {
+                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+                MetaCatUtil.debugMessage(
+                        "current node type from xml is NAMESPACE", 40);
+                MetaCatUtil.debugMessage("node type from stack: "
+                        + nameNode.getNodeType(), 40);
+                MetaCatUtil.debugMessage("current node name from xml is: "
+                        + prefixName, 40);
+                MetaCatUtil.debugMessage("node name from stack: "
+                        + nameNode.getNodeName(), 40);
+                MetaCatUtil.debugMessage("current node data from xml is: "
+                        + nameSpaceUri, 40);
+                MetaCatUtil.debugMessage("node data from stack: "
+                        + nameNode.getNodeData(), 40);
+                MetaCatUtil.debugMessage("node id is: " + nameNode.getNodeId(),
+                        40);
+                throw new SAXException(error);
+            }
+
+        }//while
+
+        //compare attributes
+        for (int i = 0; i < attributes.getLength(); i++) {
+            NodeRecord attriNode = null;
+            try {
+                attriNode = (NodeRecord) unchangableNodeStack.pop();
+
+            } catch (EmptyStackException ee) {
+                MetaCatUtil.debugMessage(
+                        "Node stack is empty for attribute data", 35);
+                throw new SAXException(error);
+            }
+            String attributeName = attributes.getQName(i);
+            String attributeValue = attributes.getValue(i);
+            MetaCatUtil.debugMessage(
+                    "current node type from xml is ATTRIBUTE ", 40);
+            MetaCatUtil.debugMessage("node type from stack: "
+                    + attriNode.getNodeType(), 40);
+            MetaCatUtil.debugMessage("current node name from xml is: "
+                    + attributeName, 40);
+            MetaCatUtil.debugMessage("node name from stack: "
+                    + attriNode.getNodeName(), 40);
+            MetaCatUtil.debugMessage("current node data from xml is: "
+                    + attributeValue, 40);
+            MetaCatUtil.debugMessage("node data from stack: "
+                    + attriNode.getNodeData(), 40);
+            MetaCatUtil.debugMessage("node id  is: " + attriNode.getNodeId(),
+                    40);
+
+            if (!attriNode.getNodeType().equals("ATTRIBUTE")
+                    || !attributeName.equals(attriNode.getNodeName())
+                    || !attributeValue.equals(attriNode.getNodeData())) {
+                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+                MetaCatUtil.debugMessage(
+                        "current node type from xml is ATTRIBUTE ", 40);
+                MetaCatUtil.debugMessage("node type from stack: "
+                        + attriNode.getNodeType(), 40);
+                MetaCatUtil.debugMessage("current node name from xml is: "
+                        + attributeName, 40);
+                MetaCatUtil.debugMessage("node name from stack: "
+                        + attriNode.getNodeName(), 40);
+                MetaCatUtil.debugMessage("current node data from xml is: "
+                        + attributeValue, 40);
+                MetaCatUtil.debugMessage("node data from stack: "
+                        + attriNode.getNodeData(), 40);
+                MetaCatUtil.debugMessage("node is: " + attriNode.getNodeId(),
+                        40);
+                throw new SAXException(error);
+            }
+        }//for
+
+    }
+
+    /* mehtod to compare current text node and node in db */
+    private void compareTextNode(Stack nodeStack, StringBuffer text,
+            String error) throws SAXException
+    {
+        NodeRecord node = null;
+        //get node from current stack
+        try {
+            node = (NodeRecord) nodeStack.pop();
+        } catch (EmptyStackException ee) {
+            MetaCatUtil.debugMessage(
+                    "Node stack is empty for text data in startElement", 35);
+            throw new SAXException(error);
         }
-        String attributeName = attributes.getQName(i);
-        String attributeValue = attributes.getValue(i);
-        MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
-        MetaCatUtil.debugMessage("node type from stack: " + 
-                                   attriNode.getNodeType(), 40);
-        MetaCatUtil.debugMessage("current node name from xml is: " + 
-                                    attributeName, 40);
-        MetaCatUtil.debugMessage("node name from stack: " +
-                                    attriNode.getNodeName(), 40);
-        MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                    attributeValue, 40);
-        MetaCatUtil.debugMessage("node data from stack: " +
-                                    attriNode.getNodeData(), 40);
-        MetaCatUtil.debugMessage("node id  is: "+ attriNode.getNodeId(), 40);
-        
-        if (!attriNode.getNodeType().equals("ATTRIBUTE") || 
-            !attributeName.equals(attriNode.getNodeName()) ||
-            !attributeValue.equals(attriNode.getNodeData()))
-        {
-          MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-          MetaCatUtil.debugMessage("current node type from xml is ATTRIBUTE ", 40);
-          MetaCatUtil.debugMessage("node type from stack: " + 
-                                   attriNode.getNodeType(), 40);
-          MetaCatUtil.debugMessage("current node name from xml is: " + 
-                                    attributeName, 40);
-          MetaCatUtil.debugMessage("node name from stack: " +
-                                    attriNode.getNodeName(), 40);
-          MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                    attributeValue, 40);
-          MetaCatUtil.debugMessage("node data from stack: " +
-                                    attriNode.getNodeData(), 40);
-          MetaCatUtil.debugMessage("node is: "+ attriNode.getNodeId(), 40);
-          throw new SAXException(error);
+        MetaCatUtil.debugMessage(
+                "current node type from xml is TEXT in start element", 40);
+        MetaCatUtil.debugMessage("node type from stack: " + node.getNodeType(),
+                40);
+        MetaCatUtil.debugMessage("current node data from xml is: "
+                + text.toString(), 40);
+        MetaCatUtil.debugMessage("node data from stack: " + node.getNodeData(),
+                40);
+        MetaCatUtil.debugMessage("node name from stack: " + node.getNodeName(),
+                40);
+        MetaCatUtil.debugMessage("node is: " + node.getNodeId(), 40);
+        if (!node.getNodeType().equals("TEXT")
+                || !(text.toString()).equals(node.getNodeData())) {
+            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+            MetaCatUtil.debugMessage(
+                    "current node type from xml is TEXT in start element", 40);
+            MetaCatUtil.debugMessage("node type from stack: "
+                    + node.getNodeType(), 40);
+            MetaCatUtil.debugMessage("current node data from xml is: "
+                    + text.toString(), 40);
+            MetaCatUtil.debugMessage("node data from stack: "
+                    + node.getNodeData(), 40);
+            MetaCatUtil.debugMessage("node name from stack: "
+                    + node.getNodeName(), 40);
+            MetaCatUtil.debugMessage("node is: " + node.getNodeId(), 40);
+            throw new SAXException(error);
+        }//if
+    }
+
+    /** SAX Handler that is called for each XML text node */
+    public void characters(char[] cbuf, int start, int len) throws SAXException
+    {
+        MetaCatUtil.debugMessage("CHARACTERS", 50);
+        if (!handleInlineData) {
+            // buffer all text nodes for same element. This is for text was
+            // splited
+            // into different nodes
+            textBuffer.append(new String(cbuf, start, len));
+            // set hittextnode true
+            hitTextNode = true;
+            // if text buffer .size is greater than max, write it to db.
+            // so we can save memory
+            if (textBuffer.length() > MAXDATACHARS) {
+                MetaCatUtil
+                        .debugMessage(
+                                "Write text into DB in charaters"
+                                        + " when text buffer size is greater than maxmum number",
+                                50);
+                DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
+                endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
+                        currentNode);
+                textBuffer = null;
+                textBuffer = new StringBuffer();
+            }
+        } else {
+            // this is inline data and write file system directly
+            // we don't need to buffered it.
+            StringBuffer inlineText = new StringBuffer();
+            inlineText.append(new String(cbuf, start, len));
+            MetaCatUtil.debugMessage(
+                    "The inline text data write into file system: "
+                            + inlineText.toString(), 50);
+            writeInlineDataIntoFile(inlineDataFileWriter, inlineText);
         }
-      }//for
-    
-  }
-  
-  /* mehtod to compare current text node and node in db*/                                         
-  private void compareTextNode(Stack nodeStack, StringBuffer text, String error) 
-                               throws SAXException
-  {
-    NodeRecord node = null;
-    //get node from current stack
-    try
-    { 
-      node = (NodeRecord)nodeStack.pop();
     }
-    catch (EmptyStackException ee)
+
+    /** SAX Handler that is called at the end of each XML element */
+    public void endElement(String uri, String localName, String qName)
+            throws SAXException
     {
-      MetaCatUtil.
-          debugMessage("Node stack is empty for text data in startElement", 35);
-      throw new SAXException(error);
-    }
-    MetaCatUtil.debugMessage("current node type from xml is TEXT in start element", 40);
-    MetaCatUtil.debugMessage("node type from stack: " + 
-                                        node.getNodeType(), 40);
-    MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                        text.toString(), 40);
-    MetaCatUtil.debugMessage("node data from stack: " +
-                                        node.getNodeData(), 40);
-    MetaCatUtil.debugMessage("node name from stack: " +
-                                        node.getNodeName(), 40);
-    MetaCatUtil.debugMessage("node is: "+ node.getNodeId(), 40);              
-    if (!node.getNodeType().equals("TEXT") || 
-        !(text.toString()).equals(node.getNodeData())) 
-    { 
-      MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-      MetaCatUtil.debugMessage("current node type from xml is TEXT in start element", 40);
-      MetaCatUtil.debugMessage("node type from stack: " + 
-                                        node.getNodeType(), 40);
-      MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                        text.toString(), 40);
-      MetaCatUtil.debugMessage("node data from stack: " +
-                                        node.getNodeData(), 40);
-      MetaCatUtil.debugMessage("node name from stack: " +
-                                        node.getNodeName(), 40);
-      MetaCatUtil.debugMessage("node is: "+ node.getNodeId(), 40);
-      throw new SAXException(error);
-    }//if
-  } 
-  
-  /** SAX Handler that is called for each XML text node */
-  public void characters(char[] cbuf, int start, int len) throws SAXException 
-  {
-     MetaCatUtil.debugMessage("CHARACTERS", 50);
-     if (!handleInlineData)
-     {
-        // buffer all text nodes for same element. This is for text was splited
-        // into different nodes
-        textBuffer.append(new String(cbuf, start,len));
-        // set hittextnode true
-        hitTextNode = true;
-        // if text buffer .size is greater than max, write it to db. 
-        // so we can save memory
-        if (textBuffer.length() > MAXDATACHARS)
-        {
-          MetaCatUtil.debugMessage("Write text into DB in charaters" + 
-                   " when text buffer size is greater than maxmum number", 50);
-          DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
-          endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, currentNode);
-          textBuffer = null;
-          textBuffer = new StringBuffer();
+        MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
+
+        if (localName.equals(INLINE) && handleInlineData) {
+            // Get the node from the stack
+            DBSAXNode currentNode = (DBSAXNode) nodeStack.pop();
+            String currentTag = currentNode.getTagName();
+            MetaCatUtil.debugMessage("End of inline data", 35);
+            // close file writer
+            try {
+                inlineDataFileWriter.close();
+                handleInlineData = false;
+            } catch (IOException ioe) {
+                throw new SAXException(ioe.getMessage());
+            }
+
+            //check if user changed inine data or not if user doesn't have
+            // write permission
+            if (startCriticalSubTree) {
+                NodeRecord node = null;
+                String inlineData;
+                try {
+                    node = (NodeRecord) currentUnChangedableSubtreeNodeStack
+                            .pop();
+                    // get file name from db
+                    String fileName = node.getNodeData();
+                    MetaCatUtil.debugMessage("in handle inline data", 35);
+                    MetaCatUtil.debugMessage(
+                            "the inline data file name from node is: "
+                                    + fileName, 40);
+                    if (!compareInlineDataFiles(fileName, inlineDataFileName)) {
+                        MetaCatUtil.debugMessage(
+                                "inline data was changed by a user"
+                                        + " who doesn't have permission", 30);
+                        throw new SAXException(PERMISSIONERROR);
+                    }
+                } catch (EmptyStackException ee) {
+                    MetaCatUtil.debugMessage(
+                            "the stack is empty for text data", 32);
+                    throw new SAXException(PERMISSIONERROR);
+                } catch (McdbException eee) {
+                    throw new SAXException(eee.getMessage());
+                } finally {
+                    // delete the inline data file already in file system
+                    deleteInlineDataFile(inlineDataFileName);
+                }
+
+            }//if
+            // write put inline data file name into text buffer (without path)
+            textBuffer = new StringBuffer(inlineDataFileName);
+            // write file name into db
+            endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
+                    currentNode);
+            // reset textbuff
+            textBuffer = null;
+            textBuffer = new StringBuffer();
+            return;
         }
-     }
-     else
-     {
-       // this is inline data and write file system directly
-       // we don't need to buffered it.
-       StringBuffer inlineText = new StringBuffer();
-       inlineText.append(new String(cbuf, start,len));
-       MetaCatUtil.debugMessage("The inline text data write into file system: "
-                                 + inlineText.toString(), 50);
-       writeInlineDataIntoFile(inlineDataFileWriter, inlineText);
-     }
-  }
-  
-  
-  /** SAX Handler that is called at the end of each XML element */
-   public void endElement(String uri, String localName,
-                          String qName) throws SAXException 
-  {
-    MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
-    
-     if (localName.equals(INLINE) && handleInlineData)
-     {
-          // Get the node from the stack
-          DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
-          String currentTag = currentNode.getTagName();
-          MetaCatUtil.debugMessage("End of inline data", 35);
-          // close file writer
-          try
-          {
-           inlineDataFileWriter.close();
-           handleInlineData = false;
-          }
-          catch (IOException ioe)
-          {
-            throw new SAXException(ioe.getMessage());
-          }
-          
-          //check if user changed inine data or not if user doesn't have
-          // write permission
-          if (startCriticalSubTree)
-          {
-            NodeRecord node = null;
-            String inlineData;
-            try
-            {
-              node = (NodeRecord)currentUnChangedableSubtreeNodeStack.pop();
-              // get file name from db
-              String fileName = node.getNodeData();
-              MetaCatUtil.debugMessage("in handle inline data", 35);
-              MetaCatUtil.debugMessage("the inline data file name from node is: "+
-                                      fileName, 40);
-              if (!compareInlineDataFiles(fileName, inlineDataFileName))
-              {
-                MetaCatUtil.debugMessage("inline data was changed by a user" +
-                                       " who doesn't have permission", 30);
-                throw new SAXException(PERMISSIONERROR);
-              }
+
+        if (!handleInlineData) {
+            // Get the node from the stack
+            DBSAXNode currentNode = (DBSAXNode) nodeStack.pop();
+            String currentTag = currentNode.getTagName();
+
+            // If before the end element, the parser hit text nodes and store
+            // them
+            // into the buffer, write the buffer to data base. The reason we
+            // put
+            // write database here is for xerces some time split text node
+            if (hitTextNode) {
+                // get access value
+                String data = null;
+                // add principal
+                if (currentTag.equals(PRINCIPAL) && accessRule != null) {
+                    data = (textBuffer.toString()).trim();
+                    accessRule.addPrincipal(data);
+
+                } else if (currentTag.equals(PERMISSION) && accessRule != null) {
+                    data = (textBuffer.toString()).trim();
+                    // we conbine different a permission into one value
+                    int permission = accessRule.getPermission();
+                    // add permision
+                    if (data.toUpperCase().equals(READSTRING)) {
+                        permission = permission | READ;
+                    } else if (data.toUpperCase().equals(WRITESTRING)) {
+                        permission = permission | WRITE;
+                    } else if (data.toUpperCase().equals(CHMODSTRING)) {
+                        permission = permission | CHMOD;
+                    } else if (data.toUpperCase().equals(ALLSTRING)) {
+                        permission = permission | ALL;
+                    }
+                    accessRule.setPermission(permission);
+                }
+                // put additionalmetadata/describes into vector
+                else if (currentTag.equals(DESCRIBES)) {
+                    data = (textBuffer.toString()).trim();
+                    describesId.add(data);
+                } else if (currentTag.equals(REFERENCES)
+                        && (processTopLeverAccess || processAdditionalAccess || processOtherAccess)) {
+                    // get reference
+                    data = (textBuffer.toString()).trim();
+                    // put reference id into accessSection
+                    accessObject.setReferences(data);
+
+                } else if (currentTag.equals(URL)) {
+                    //handle online data, make sure its'parent is online
+                    DBSAXNode parentNode = (DBSAXNode) nodeStack.peek();
+                    if (parentNode != null && parentNode.getTagName() != null
+                            && parentNode.getTagName().equals(ONLINE)) {
+                        // if online data is in local metacat, add it to the
+                        // vector
+                        data = (textBuffer.toString()).trim();
+                        if (data != null
+                                && (data.indexOf(MetaCatUtil
+                                        .getOption("httpserver")) != -1 || data
+                                        .indexOf(MetaCatUtil
+                                                .getOption("server")) != -1)) {
+                            // Get docid from url
+                            String dataId = MetaCatUtil
+                                    .getDocIdWithRevFromOnlineURL(data);
+                            // add to vector
+                            onlineDataFileIdVector.add(dataId);
+                        }//if
+                    }//if
+                }//else if
+                // write text to db if it is not inline data
+                //if (!localName.equals(INLINE))
+                {
+                    MetaCatUtil.debugMessage(
+                            "Write text into DB in End Element", 50);
+                    //compare text node if need
+                    if (startCriticalSubTree) {
+                        compareTextNode(currentUnChangedableSubtreeNodeStack,
+                                textBuffer, PERMISSIONERROR);
+                    }//if
+                    //compare top level access module
+                    if (processTopLeverAccess && needCheckingAccessModule) {
+                        compareTextNode(
+                                currentUnchangableAccessModuleNodeStack,
+                                textBuffer, UPDATEACCESSERROR);
+                    }
+                    // write text node into db
+                    endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
+                            currentNode);
+                }
+                if (needCheckingAccessModule
+                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
+                    // stored the pull out nodes into storedNode stack
+                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT",
+                            null, null, MetaCatUtil.normalize(textBuffer
+                                    .toString()));
+                    storedAccessNodeStack.push(nodeElement);
+
+                }
+            }//if
+
+            //end crtical subtree(user doesn't have permission to write)
+            //When reach the first element and stack is empty
+            if (localName.equals(firstElementNameForCriticalSubTree)
+                    && currentUnChangedableSubtreeNodeStack.isEmpty()) {
+                startCriticalSubTree = false;
             }
-            catch (EmptyStackException ee)
-            {
-              MetaCatUtil.debugMessage("the stack is empty for text data", 32);
-              throw new SAXException(PERMISSIONERROR);
+
+            //set hitText false
+            hitTextNode = false;
+            // reset textbuff
+            textBuffer = null;
+            textBuffer = new StringBuffer();
+
+            // hand sub stree stuff
+            if (!subTreeInfoStack.empty()) {
+                SubTree tree = (SubTree) subTreeInfoStack.peek();// get last
+                                                                 // subtree
+                if (tree != null && tree.getStartElementName() != null
+                        && (tree.getStartElementName()).equals(currentTag)) {
+                    // find the end of sub tree and set the end node id
+                    tree.setEndNodeId(endNodeId);
+                    // add the subtree into the final store palace
+                    subTreeList.add(tree);
+                    // get rid of it from stack
+                    subTreeInfoStack.pop();
+                }//if
+            }//if
+
+            // access stuff
+            if (currentTag.equals(ALLOW) || currentTag.equals(DENY)) {
+                // finish parser a ccess rule and assign it to new one
+                AccessRule newRule = accessRule;
+                //add the new rule to access section object
+                accessObject.addAccessRule(newRule);
+                // reset access rule
+                accessRule = null;
+            } else if (currentTag.equals(ACCESS)) {
+                // finish parse a access setction and assign it to new one
+
+                accessObject.setEndNodeId(endNodeId);
+                AccessSection newAccessObject = accessObject;
+
+                if (newAccessObject != null) {
+
+                    // add the accessSection into a vector to store it
+                    // if it is not a reference, need to store it
+                    if (newAccessObject.getReferences() == null) {
+
+                        newAccessObject
+                                .setStoredTmpNodeStack(storedAccessNodeStack);
+                        accessObjectList.add(newAccessObject);
+                    }
+                    if (processTopLeverAccess) {
+
+                        // top level access control will handle whole document
+                        // -docid
+                        topLevelAccessControlMap.put(docid, newAccessObject);
+                        // reset processtopleveraccess tag
+
+                    }//if
+                    else if (processAdditionalAccess) {
+                        // for additional control
+                        // put everything in describes value and access object
+                        // into hash
+                        for (int i = 0; i < describesId.size(); i++) {
+
+                            String subId = (String) describesId.elementAt(i);
+                            if (subId != null) {
+                                additionalAccessControlMap.put(subId,
+                                        newAccessObject);
+                            }//if
+                        }//for
+                        // add this hashtable in to vector
+
+                        additionalAccessMapList.add(additionalAccessControlMap);
+                        // reset this hashtable in order to store another
+                        // additional
+                        //accesscontrol
+                        additionalAccessControlMap = null;
+                        additionalAccessControlMap = new Hashtable();
+                    }//if
+
+                }//if
+                //check if access node stack is empty after parsing top access
+                //module
+
+                if (needCheckingAccessModule && processTopLeverAccess
+                        && !currentUnchangableAccessModuleNodeStack.isEmpty()) {
+
+                    MetaCatUtil.debugMessage(
+                            "Access node stack is not empty after "
+                                    + "parsing access subtree", 40);
+                    throw new SAXException(UPDATEACCESSERROR);
+
+                }
+                //reset access section object
+
+                accessObject = null;
+
+                // reset tmp stored node stack
+                storedAccessNodeStack = null;
+                storedAccessNodeStack = new Stack();
+
+                // reset flag
+                processAdditionalAccess = false;
+                processTopLeverAccess = false;
+                processOtherAccess = false;
+
+            } else if (currentTag.equals(ADDITIONALMETADATA)) {
+                //reset describesId
+                describesId = null;
+                describesId = new Vector();
             }
-            catch (McdbException eee)
-            {
-              throw new SAXException(eee.getMessage());
-            }
-            finally
-            {
-              // delete the inline data file already in file system
-              deleteInlineDataFile(inlineDataFileName);
-            }
-          
-          }//if
-          // write put inline data file name into text buffer (without path)
-          textBuffer = new StringBuffer(inlineDataFileName);
-          // write file name into db
-          endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, currentNode);
-          // reset textbuff
-          textBuffer = null;
-          textBuffer = new StringBuffer(); 
-          return;
+        } else {
+            // this is in inline part
+            StringBuffer endElement = new StringBuffer();
+            endElement.append("</");
+            endElement.append(qName);
+            endElement.append(">");
+            MetaCatUtil.debugMessage("inline endElement: "
+                    + endElement.toString(), 50);
+            writeInlineDataIntoFile(inlineDataFileWriter, endElement);
+        }
     }
-    
-    if (!handleInlineData)
+
+    /**
+     * SAX Handler that receives notification of comments in the DTD
+     */
+    public void comment(char[] ch, int start, int length) throws SAXException
     {
-     // Get the node from the stack
-     DBSAXNode currentNode = (DBSAXNode)nodeStack.pop();
-     String currentTag = currentNode.getTagName();
-    
-     // If before the end element, the parser hit text nodes and store them
-     // into the buffer, write the buffer to data base. The reason we put
-     // write database here is for xerces some time split text node
-     if (hitTextNode)
-     {
-        // get access value
-        String data = null;
-        // add principal
-       if (currentTag.equals(PRINCIPAL) && accessRule != null) 
-       {
-          data = (textBuffer.toString()).trim();
-          accessRule.addPrincipal(data);
+        MetaCatUtil.debugMessage("COMMENT", 50);
+        if (!handleInlineData) {
+            if (!processingDTD) {
+                DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
+                String str = new String(ch, start, length);
 
-       } 
-       else if (currentTag.equals(PERMISSION) && accessRule != null) 
-       {
-         data = (textBuffer.toString()).trim();
-         // we conbine different a permission into one value
-         int permission = accessRule.getPermission();
-         // add permision
-         if ( data.toUpperCase().equals(READSTRING) ) 
-         {
-           permission = permission | READ;
-         } 
-         else if ( data.toUpperCase().equals(WRITESTRING) ) 
-         {
-           permission = permission | WRITE;
-         } 
-         else if ( data.toUpperCase().equals(CHMODSTRING)) 
-         {
-           permission = permission | CHMOD;
-         } 
-         else if ( data.toUpperCase().equals(ALLSTRING) ) 
-         {
-          permission = permission | ALL;
-         }
-         accessRule.setPermission(permission);
-       }
-       // put additionalmetadata/describes into vector
-       else if (currentTag.equals(DESCRIBES))
-       {
-          data = (textBuffer.toString()).trim();
-          describesId.add(data);
-       }
-       else if (currentTag.equals(REFERENCES) && 
-               (processTopLeverAccess ||
-                processAdditionalAccess || processOtherAccess))
-       {
-         // get reference 
-         data = (textBuffer.toString()).trim();
-         // put reference id into accessSection
-         accessObject.setReferences(data);
-         
-       }
-       else if (currentTag.equals(URL))
-       {
-         //handle online data, make sure its'parent is online
-         DBSAXNode parentNode = (DBSAXNode)nodeStack.peek();
-         if (parentNode != null && parentNode.getTagName()!= null &&
-             parentNode.getTagName().equals(ONLINE))
-         {
-            // if online data is in local metacat, add it to the vector
-            data = (textBuffer.toString()).trim();
-            if (data != null && 
-                (data.indexOf(MetaCatUtil.getOption("httpserver")) != -1 || 
-                data.indexOf(MetaCatUtil.getOption("server")) != -1))
-            {
-              // Get docid from url
-              String dataId =MetaCatUtil.getDocIdWithRevFromOnlineURL(data);
-              // add to vector
-              onlineDataFileIdVector.add(dataId);             
-            }//if
-          }//if
-       }//else if
-       // write text to db if it is not inline data
-       //if (!localName.equals(INLINE))
-       {
-          MetaCatUtil.debugMessage("Write text into DB in End Element", 50);
-          //compare text node if need
-          if (startCriticalSubTree)
-          {
-            compareTextNode(currentUnChangedableSubtreeNodeStack, textBuffer, 
-                            PERMISSIONERROR);
-          }//if
-          //compare top level access module
-          if (processTopLeverAccess && needCheckingAccessModule)
-          {
-             compareTextNode(currentUnchangableAccessModuleNodeStack, 
-                            textBuffer, UPDATEACCESSERROR);
-          }
-          // write text node into db
-          endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer, currentNode);
-       }
-       if (needCheckingAccessModule && 
-       (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
-       {
-        // stored the pull out nodes into storedNode stack
-        NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT", 
-                      null, null, MetaCatUtil.normalize(textBuffer.toString()));
-        storedAccessNodeStack.push(nodeElement);
-                                         
-      }
-     }//if
-     
-     //end crtical subtree(user doesn't have permission to write)
-     //When reach the first element and stack is empty
-     if (localName.equals(firstElementNameForCriticalSubTree) && 
-         currentUnChangedableSubtreeNodeStack.isEmpty()) 
-     {
-       startCriticalSubTree = false;
-     }
-     
-     
-     //set hitText false
-     hitTextNode = false;
-     // reset textbuff
-     textBuffer = null;
-     textBuffer = new StringBuffer();
-     
-     // hand sub stree stuff
-     if (!subTreeInfoStack.empty())
-     {
-       SubTree tree = (SubTree)subTreeInfoStack.peek();// get last subtree
-       if (tree != null && tree.getStartElementName() != null && 
-         (tree.getStartElementName()).equals(currentTag))
-       {
-         // find the end of sub tree and set the end node id
-         tree.setEndNodeId(endNodeId);
-         // add the subtree into the final store palace
-         subTreeList.add(tree);
-         // get rid of it from stack
-         subTreeInfoStack.pop();
-       }//if
-     }//if
+                //compare comment if need
+                if (startCriticalSubTree) {
+                    compareCommentNode(currentUnChangedableSubtreeNodeStack,
+                            str, PERMISSIONERROR);
+                }//if
+                //compare top level access module
+                if (processTopLeverAccess && needCheckingAccessModule) {
+                    compareCommentNode(currentUnchangableAccessModuleNodeStack,
+                            str, UPDATEACCESSERROR);
+                }
+                endNodeId = currentNode.writeChildNodeToDB("COMMENT", null,
+                        str, docid);
+                if (needCheckingAccessModule
+                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
+                    // stored the pull out nodes into storedNode stack
+                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2,
+                            "COMMENT", null, null, MetaCatUtil.normalize(str));
+                    storedAccessNodeStack.push(nodeElement);
 
-     // access stuff
-     if (currentTag.equals(ALLOW) || currentTag.equals(DENY))
-     {
-       // finish parser a ccess rule and  assign it to new one
-       AccessRule newRule = accessRule;
-       //add the new rule to access section object
-       accessObject.addAccessRule(newRule);
-       // reset access rule
-       accessRule = null;
-     }
-     else if (currentTag.equals(ACCESS))
-     {
-       // finish parse a access setction and assign it to new one
-      
-       accessObject.setEndNodeId(endNodeId);
-       AccessSection newAccessObject = accessObject;
-    
-       if (newAccessObject != null)
-       {
-       
-        // add the accessSection into a vector to store it
-        // if it is not a reference, need to store it
-        if ( newAccessObject.getReferences() == null)
-        {
-          
-          newAccessObject.setStoredTmpNodeStack(storedAccessNodeStack);
-          accessObjectList.add(newAccessObject);
+                }
+            }
+        } else {
+            // inline data comment
+            StringBuffer inlineComment = new StringBuffer();
+            inlineComment.append("<!--");
+            inlineComment.append(new String(ch, start, length));
+            inlineComment.append("-->");
+            MetaCatUtil.debugMessage("inline data comment: "
+                    + inlineComment.toString(), 50);
+            writeInlineDataIntoFile(inlineDataFileWriter, inlineComment);
         }
-        if (processTopLeverAccess)
-        {
-          
-          // top level access control will handle whole document -docid
-          topLevelAccessControlMap.put(docid, newAccessObject);
-          // reset processtopleveraccess tag
-          
+    }
+
+    /* Comparet comment from xml and db */
+    private void compareCommentNode(Stack nodeStack, String string, String error)
+            throws SAXException
+    {
+        NodeRecord node = null;
+        try {
+            node = (NodeRecord) nodeStack.pop();
+        } catch (EmptyStackException ee) {
+            MetaCatUtil.debugMessage("the stack is empty for comment data", 32);
+            throw new SAXException(error);
+        }
+        MetaCatUtil.debugMessage("current node type from xml is COMMENT", 40);
+        MetaCatUtil.debugMessage("node type from stack: " + node.getNodeType(),
+                40);
+        MetaCatUtil
+                .debugMessage("current node data from xml is: " + string, 40);
+        MetaCatUtil.debugMessage("node data from stack: " + node.getNodeData(),
+                40);
+        MetaCatUtil.debugMessage("node is from stack: " + node.getNodeId(), 40);
+        // if not consistent terminate program and throw a exception
+        if (!node.getNodeType().equals("COMMENT")
+                || !string.equals(node.getNodeData())) {
+            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+            MetaCatUtil.debugMessage("current node type from xml is COMMENT",
+                    40);
+            MetaCatUtil.debugMessage("node type from stack: "
+                    + node.getNodeType(), 40);
+            MetaCatUtil.debugMessage(
+                    "current node data from xml is: " + string, 40);
+            MetaCatUtil.debugMessage("node data from stack: "
+                    + node.getNodeData(), 40);
+            MetaCatUtil.debugMessage("node is from stack: " + node.getNodeId(),
+                    40);
+            throw new SAXException(error);
         }//if
-        else if (processAdditionalAccess)
-        {
-          // for additional control
-          // put everything in describes value and access object into hash
-          for ( int i=0; i<describesId.size(); i++)
-          {
-           
-            String subId = (String)describesId.elementAt(i);
-            if (subId != null)
-            {
-              additionalAccessControlMap.put(subId, newAccessObject);
-            }//if
-          }//for
-          // add this hashtable in to vector
-         
-          additionalAccessMapList.add(additionalAccessControlMap);
-          // reset this hashtable in order to store another additional 
-          //accesscontrol
-          additionalAccessControlMap = null;
-          additionalAccessControlMap = new Hashtable();
-        }//if
-       
-       }//if
-       //check if  access node stack is empty after parsing top access
-       //module
-      
-       if (needCheckingAccessModule && processTopLeverAccess && 
-           !currentUnchangableAccessModuleNodeStack.isEmpty())
-       {
-         
-         MetaCatUtil.debugMessage("Access node stack is not empty after " + 
-                                   "parsing access subtree", 40);
-         throw new SAXException(UPDATEACCESSERROR);
-                                  
-       }
-       //reset access section object
-      
-       accessObject = null;
-     
-       // reset tmp stored node stack
-       storedAccessNodeStack = null;
-       storedAccessNodeStack = new Stack();
-    
-       // reset flag
-       processAdditionalAccess =false;
-       processTopLeverAccess =false;
-       processOtherAccess = false;
-      
-     }
-     else if (currentTag.equals(ADDITIONALMETADATA))
-     {
-        //reset describesId
-        describesId = null;
-        describesId = new Vector();
-     }
     }
-    else
+
+    /**
+     * SAX Handler called once for each processing instruction found: node that
+     * PI may occur before or after the root element.
+     */
+    public void processingInstruction(String target, String data)
+            throws SAXException
     {
-      // this is in inline part
-      StringBuffer endElement = new StringBuffer();
-      endElement.append("</");
-      endElement.append(qName);
-      endElement.append(">");
-      MetaCatUtil.debugMessage("inline endElement: " +
-                                endElement.toString(), 50);
-      writeInlineDataIntoFile(inlineDataFileWriter, endElement);
+        MetaCatUtil.debugMessage("PI", 50);
+        if (!handleInlineData) {
+            DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
+            endNodeId = currentNode.writeChildNodeToDB("PI", target, data,
+                    docid);
+        } else {
+            StringBuffer inlinePI = new StringBuffer();
+            inlinePI.append("<?");
+            inlinePI.append(target);
+            inlinePI.append(" ");
+            inlinePI.append(data);
+            inlinePI.append("?>");
+            MetaCatUtil.debugMessage("inline data pi is: "
+                    + inlinePI.toString(), 50);
+            writeInlineDataIntoFile(inlineDataFileWriter, inlinePI);
+        }
     }
-  }
-   
-   /**
-    * SAX Handler that receives notification of comments in the DTD
-    */
-   public void comment(char[] ch, int start, int length) throws SAXException 
-   {
-     MetaCatUtil.debugMessage("COMMENT", 50);
-     if ( !handleInlineData)
-     {
-       if ( !processingDTD ) 
-       {
-         DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
-         String str = new String(ch, start, length);
-       
-         //compare comment if need
-         if (startCriticalSubTree)
-         {
-           compareCommentNode(currentUnChangedableSubtreeNodeStack, str, 
-                            PERMISSIONERROR);
-         }//if
-         //compare top level access module
-         if (processTopLeverAccess && needCheckingAccessModule)
-         {
-           compareCommentNode(currentUnchangableAccessModuleNodeStack, str,
-                            UPDATEACCESSERROR);
-         }
-         endNodeId = currentNode.writeChildNodeToDB("COMMENT", null, str, docid);
-         if (needCheckingAccessModule && 
-         (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
-         {
-          // stored the pull out nodes into storedNode stack
-          NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "COMMENT", 
-                                        null, null, MetaCatUtil.normalize(str));
-          storedAccessNodeStack.push(nodeElement);
-                                         
+
+    /** SAX Handler that is called at the start of Namespace */
+    public void startPrefixMapping(String prefix, String uri)
+            throws SAXException
+    {
+        MetaCatUtil.debugMessage("NAMESPACE", 50);
+        if (!handleInlineData) {
+            namespaces.put(prefix, uri);
+        } else {
+            inlineDataNameSpace.put(prefix, uri);
         }
-       }
-     }
-     else
-     {
-       // inline data comment
-       StringBuffer inlineComment = new StringBuffer();
-       inlineComment.append("<!--");
-       inlineComment.append(new String(ch, start, length));
-       inlineComment.append("-->");
-       MetaCatUtil.debugMessage("inline data comment: "+ 
-                                 inlineComment.toString(), 50);
-       writeInlineDataIntoFile(inlineDataFileWriter, inlineComment);
-     }
-   }
-   
-   
-   /* Comparet comment from xml and db */
-   private void compareCommentNode(Stack nodeStack, String string, String error)
-                                   throws SAXException
-   {
-     NodeRecord node = null;
-     try
-     {
-       node = (NodeRecord)nodeStack.pop();
-     }
-     catch (EmptyStackException ee)
-     {
-       MetaCatUtil.debugMessage("the stack is empty for comment data", 32);
-       throw new SAXException(error);
-     }
-     MetaCatUtil.debugMessage("current node type from xml is COMMENT", 40);
-     MetaCatUtil.debugMessage("node type from stack: " + 
-                                    node.getNodeType(), 40);
-     MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                    string, 40);
-     MetaCatUtil.debugMessage("node data from stack: " +
-                                    node.getNodeData(), 40);
-     MetaCatUtil.debugMessage("node is from stack: " + 
-                                    node.getNodeId(), 40);
-     // if not consistent terminate program and throw a exception
-     if (!node.getNodeType().equals("COMMENT") || 
-         !string.equals(node.getNodeData())) 
-     { 
-       MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-       MetaCatUtil.debugMessage("current node type from xml is COMMENT", 40);
-       MetaCatUtil.debugMessage("node type from stack: " + 
-                                    node.getNodeType(), 40);
-       MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                    string, 40);
-       MetaCatUtil.debugMessage("node data from stack: " +
-                                    node.getNodeData(), 40);
-       MetaCatUtil.debugMessage("node is from stack: " + 
-                                        node.getNodeId(), 40);
-       throw new SAXException(error);
-     }//if
-   }
-   
-   /**
-    * SAX Handler called once for each processing instruction found:
-    * node that PI may occur before or after the root element.
-    */
-   public void processingInstruction(String target, String data)
-          throws SAXException 
-  {
-     MetaCatUtil.debugMessage("PI", 50);
-     if (!handleInlineData)
-     {
-       DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
-       endNodeId = currentNode.writeChildNodeToDB("PI", target, data, docid);
-     }
-     else
-     {
-       StringBuffer inlinePI = new StringBuffer();
-       inlinePI.append("<?");
-       inlinePI.append(target);
-       inlinePI.append(" ");
-       inlinePI.append(data);
-       inlinePI.append("?>");
-       MetaCatUtil.debugMessage("inline data pi is: " + 
-                                 inlinePI.toString(), 50);
-       writeInlineDataIntoFile(inlineDataFileWriter, inlinePI);
-     }
-   }
+    }
 
-  /** SAX Handler that is called at the start of Namespace */
-   public void startPrefixMapping(String prefix, String uri)
-                                          throws SAXException
-   {
-    MetaCatUtil.debugMessage("NAMESPACE", 50);
-    if (!handleInlineData)
+    /**
+     * SAX Handler that is called for each XML text node that is Ignorable
+     * white space
+     */
+    public void ignorableWhitespace(char[] cbuf, int start, int len)
+            throws SAXException
     {
-      namespaces.put(prefix, uri);
+        // When validation is turned "on", white spaces are reported here
+        // When validation is turned "off" white spaces are not reported here,
+        // but through characters() callback
+        MetaCatUtil.debugMessage("IGNORABLEWHITESPACE", 50);
+        if (!handleInlineData) {
+            DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
+            String data = null;
+            int leftover = len;
+            int offset = start;
+            boolean moredata = true;
+
+            // This loop deals with the case where there are more characters
+            // than can fit in a single database text field (limit is
+            // MAXDATACHARS). If the text to be inserted exceeds MAXDATACHARS,
+            // write a series of nodes that are MAXDATACHARS long, and then the
+            // final node contains the remainder
+            while (moredata) {
+                if (leftover > MAXDATACHARS) {
+                    data = new String(cbuf, offset, MAXDATACHARS);
+                    leftover -= MAXDATACHARS;
+                    offset += MAXDATACHARS;
+                } else {
+                    data = new String(cbuf, offset, leftover);
+                    moredata = false;
+                }
+
+                //compare whitespace if need
+                if (startCriticalSubTree) {
+                    compareWhiteSpace(currentUnChangedableSubtreeNodeStack,
+                            data, PERMISSIONERROR);
+                }//if
+
+                //compare whitespace in access top module
+                if (processTopLeverAccess && needCheckingAccessModule) {
+                    compareWhiteSpace(currentUnchangableAccessModuleNodeStack,
+                            data, UPDATEACCESSERROR);
+                }
+                // Write the content of the node to the database
+                if (needCheckingAccessModule
+                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
+                    // stored the pull out nodes into storedNode stack
+                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT",
+                            null, null, MetaCatUtil.normalize(data));
+                    storedAccessNodeStack.push(nodeElement);
+
+                }
+                endNodeId = currentNode.writeChildNodeToDB("TEXT", null, data,
+                        docid);
+            }
+        } else {
+            //This is inline data write to file directly
+            StringBuffer inlineWhiteSpace = new StringBuffer(new String(cbuf,
+                    start, len));
+            writeInlineDataIntoFile(inlineDataFileWriter, inlineWhiteSpace);
+        }
+
     }
-    else
+
+    /* Compare whitespace from xml and db */
+    private void compareWhiteSpace(Stack nodeStack, String string, String error)
+            throws SAXException
     {
-      inlineDataNameSpace.put(prefix, uri);
+        NodeRecord node = null;
+        try {
+            node = (NodeRecord) nodeStack.pop();
+        } catch (EmptyStackException ee) {
+            MetaCatUtil.debugMessage("the stack is empty for whitespace data",
+                    32);
+            throw new SAXException(error);
+        }
+        if (!node.getNodeType().equals("TEXT")
+                || !string.equals(node.getNodeData())) {
+            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
+            MetaCatUtil.debugMessage(
+                    "current node type from xml is WHITESPACE TEXT", 40);
+            MetaCatUtil.debugMessage("node type from stack: "
+                    + node.getNodeType(), 40);
+            MetaCatUtil.debugMessage(
+                    "current node data from xml is: " + string, 40);
+            MetaCatUtil.debugMessage("node data from stack: "
+                    + node.getNodeData(), 40);
+            MetaCatUtil.debugMessage("node is from stack: " + node.getNodeId(),
+                    40);
+            throw new SAXException(error);
+        }//if
     }
-   }
-      /**
-    * SAX Handler that is called for each XML text node that is
-    * Ignorable white space
-    */
-   public void ignorableWhitespace(char[] cbuf, int start, int len)
-               throws SAXException 
-  {
-     // When validation is turned "on", white spaces are reported here
-     // When validation is turned "off" white spaces are not reported here,
-     // but through characters() callback
-     MetaCatUtil.debugMessage("IGNORABLEWHITESPACE", 50);
-     if (!handleInlineData)
-     {
-       DBSAXNode currentNode = (DBSAXNode)nodeStack.peek();
-       String data = null;
-       int leftover = len;
-       int offset = start;
-       boolean moredata = true;
 
-       // This loop deals with the case where there are more characters
-       // than can fit in a single database text field (limit is
-       // MAXDATACHARS).  If the text to be inserted exceeds MAXDATACHARS,
-       // write a series of nodes that are MAXDATACHARS long, and then the
-       // final node contains the remainder
-       while (moredata) 
-       {
-         if (leftover > MAXDATACHARS) 
-         {
-           data = new String(cbuf, offset, MAXDATACHARS);
-           leftover -= MAXDATACHARS;
-           offset += MAXDATACHARS;
-         } 
-         else 
-         {
-           data = new String(cbuf, offset, leftover);
-           moredata = false;
-         }
+    /** SAX Handler that receives notification of end of the document */
+    public void endDocument() throws SAXException
+    {
+        MetaCatUtil.debugMessage("end Document", 50);
+        // There are some unchangable subtree didn't be compare
+        // This maybe cause user change the subtree id
+        if (!unChangableSubTreeHash.isEmpty()) {
+            MetaCatUtil.debugMessage("The unChangealbe subtree is not empty",
+                    40);
+            throw new SAXException(PERMISSIONERROR);
+        }
 
-         //compare whitespace if need
-         if (startCriticalSubTree)
-         {
-           compareWhiteSpace(currentUnChangedableSubtreeNodeStack, data, 
-                           PERMISSIONERROR);
-         }//if
-       
-         //compare whitespace in access top module
-         if (processTopLeverAccess && needCheckingAccessModule)
-         {
-           compareWhiteSpace(currentUnchangableAccessModuleNodeStack, data, 
-                           UPDATEACCESSERROR);
-         }
-         // Write the content of the node to the database
-         if (needCheckingAccessModule && 
-         (processAdditionalAccess || processOtherAccess || processTopLeverAccess))
-         {
-          // stored the pull out nodes into storedNode stack
-          NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT", 
-                                     null, null, MetaCatUtil.normalize(data));
-          storedAccessNodeStack.push(nodeElement);
-                                         
-         }
-         endNodeId = currentNode.writeChildNodeToDB("TEXT", null, data, docid);
-       }
-     }
-     else
-     {
-       //This is inline data write to file directly
-       StringBuffer inlineWhiteSpace = new 
-                                     StringBuffer(new String(cbuf, start, len));
-       writeInlineDataIntoFile(inlineDataFileWriter, inlineWhiteSpace);
-     }
-       
-   }
-   
-   /* Compare whitespace from xml and db */
-   private void compareWhiteSpace(Stack nodeStack, String string, String error)
-                                  throws SAXException
-   {
-      NodeRecord node = null;
-      try
-      {
-        node = (NodeRecord)nodeStack.pop();
-      }
-      catch (EmptyStackException ee)
-      {
-        MetaCatUtil.debugMessage("the stack is empty for whitespace data", 32);
-        throw new SAXException(error);
-      }
-      if (!node.getNodeType().equals("TEXT") || 
-          !string.equals(node.getNodeData())) 
-      { 
-        MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
-        MetaCatUtil.debugMessage("current node type from xml is WHITESPACE TEXT", 40);
-        MetaCatUtil.debugMessage("node type from stack: " + 
-                                  node.getNodeType(), 40);
-        MetaCatUtil.debugMessage("current node data from xml is: " + 
-                                  string, 40);
-        MetaCatUtil.debugMessage("node data from stack: " +
-                                  node.getNodeData(), 40);
-        MetaCatUtil.debugMessage("node is from stack: " + 
-                                  node.getNodeId(), 40);
-        throw new SAXException(error);
-     }//if
-   }
-   
-   /** SAX Handler that receives notification of end of the document */
-   public void endDocument() throws SAXException 
-   {
-     MetaCatUtil.debugMessage("end Document", 50);
-     // There are some unchangable subtree didn't be compare
-     // This maybe cause user change the subtree id
-     if (!unChangableSubTreeHash.isEmpty())
-     {
-       MetaCatUtil.debugMessage("The unChangealbe subtree is not empty", 40);
-       throw new SAXException(PERMISSIONERROR);
-     }
-     
-     // write access rule to db
-     writeAccessRuleToDB();
-     
-     //delete relation table
-     deleteRelations();
-     //write relations
-     for (int i= 0; i<onlineDataFileIdVector.size(); i++)
-     {
-       String id = (String)onlineDataFileIdVector.elementAt(i);
-       writeOnlineDataFileIdIntoRelationTable(id);
-     }
-   
-     // Starting new thread for writing XML Index.
-     // It calls the run method of the thread.
-     boolean useXMLIndex = 
-         (new Boolean(MetaCatUtil.getOption("usexmlindex"))).booleanValue();
-     if (useXMLIndex) {
+        // write access rule to db
+        writeAccessRuleToDB();
+
+        //delete relation table
+        deleteRelations();
+        //write relations
+        for (int i = 0; i < onlineDataFileIdVector.size(); i++) {
+            String id = (String) onlineDataFileIdVector.elementAt(i);
+            writeOnlineDataFileIdIntoRelationTable(id);
+        }
+
+        // Starting new thread for writing XML Index.
+        // It calls the run method of the thread.
+        boolean useXMLIndex = (new Boolean(MetaCatUtil.getOption("usexmlindex")))
+                .booleanValue();
+        if (useXMLIndex) {
             try {
                 xmlIndex.start();
             } catch (NullPointerException e) {
@@ -1488,838 +1427,748 @@
                         "Problem with starting thread for writing XML Index. "
                                 + e.getMessage());
             }
-     }
-   }
-   
-  /* The method to write all access rule into db */
-  private void writeAccessRuleToDB() throws SAXException
-  {
-    //Delete old permssion
-    deletePermissionsInAccessTable(docid);
-    //write top leve access rule
-    writeTopLevelAccessRuleToDB();
-    //write additional access rule
-    //writeAddtionalAccessRuleToDB();
-  }//writeAccessRuleToDB
-   
-  /* The method to write top level access rule into db. */
-  private void writeTopLevelAccessRuleToDB() throws SAXException
-  {
-    
-    // for top document level
-    Object accessSection = topLevelAccessControlMap.get(docid);
-    boolean top = true;
-    String subSectionId = null;
-    if ( accessSection != null )
-    {
-       AccessSection accessSectionObj = (AccessSection)accessSection;
-           
-       // if accessSection is not null and is not reference
-       if ( accessSectionObj.getReferences() == null)
-       {
-          // write the top level access module into xml_accesssubtree to store info
-          // and then when update to check if the user can update it or not
-          deleteAccessSubTreeRecord(docid);
-          writeAccessSubTreeIntoDB(accessSectionObj,TOPLEVEL);
-         
-          //write access section into xml_access table
-          writeGivenAccessRuleIntoDB(accessSectionObj, top, subSectionId);
-          // write relative online data file into xml_access too.
-          /*for (int i= 0; i<onlineDataFileIdVector.size(); i++)
-          {
-            String id = (String)onlineDataFileIdVector.elementAt(i);
-            writeAccessRuleForRalatedDataFileIntoDB(accessSectionObj, id);
-          }*/
-          
-       }
-       else
-       {
-   
-        // this is a reference and go trough the vector which contains all
-        // access object
-        String referenceId = accessSectionObj.getReferences();
-        boolean findAccessObject = false;
-        MetaCatUtil.debugMessage("referered id for top access: "+ 
-                               referenceId, 35);
-        for (int i=0; i<accessObjectList.size(); i++)
-        {
-          AccessSection accessObj = (AccessSection)accessObjectList.elementAt(i);
-          String accessObjId = accessObj.getSubTreeId();
-          if (referenceId != null && accessObj != null &&
-              referenceId.equals(accessObjId))
-          {
-            // make sure the user didn't change any thing in this access moduel
-            // too if user doesn't have all permission
-            if (needCheckingAccessModule)
-            {
-              
-              Stack newStack = accessObj.getStoredTmpNodeStack();
-              //revise order
-              newStack = MetaCatUtil.reviseStack(newStack);
-               // go throught the vector of unChangableAccessSubtreevector
-              // and find the one whose id is as same as referenceid
-              AccessSection oldAccessObj = 
-                       getAccessSectionFromUnchangableAccessVector(referenceId);
-              //if oldAccessObj is null something is wrong
-              if (oldAccessObj == null)
-              {
-                throw new SAXException(UPDATEACCESSERROR);
-              }//if
-              else
-              {
-                // Get the node stack from old access obj
-                Stack oldStack = oldAccessObj.getSubTreeNodeStack();
-                comparingNodeStacks(newStack, oldStack);
-              }//else
-            }//if
-            // write accessobject into db
-            writeGivenAccessRuleIntoDB(accessObj, top, subSectionId);
-            // add access rule for related on line data id too.
-            /*for (int j= 0; j<onlineDataFileIdVector.size(); j++)
-            {
-              String id = (String)onlineDataFileIdVector.elementAt(j);
-              writeAccessRuleForRalatedDataFileIntoDB(accessObj, id);
-            }*/
-            
-            
-            //write the reference access into xml_accesssubtree too
-             // write the top level access module into xml_accesssubtree to store info
-             // and then when update to check if the user can update it or not
-            deleteAccessSubTreeRecord(docid);
-            writeAccessSubTreeIntoDB(accessSectionObj,TOPLEVEL);
-            writeAccessSubTreeIntoDB(accessObj, SUBTREELEVEL);
-            findAccessObject = true;
-            break;
-          }
-        }//for
-        // if we couldn't find an access subtree id for this reference id
-        if (!findAccessObject)
-        {
-          throw new SAXException("The referenceid: " + referenceId +
-                               " is not access subtree");
-        }//if
-      }//else
-      
-     
-    }//if
-    else
-    {
-      // couldn't find a access section object 
-      MetaCatUtil.debugMessage("couldn't find access control for document: "+
-                                docid, 35);
+        }
     }
-    
-  }//writeTopLevelAccessRuletoDB
-  
-  /* Given a subtree id and find the responding access section*/
-  private AccessSection getAccessSectionFromUnchangableAccessVector(String id)
-  {
-    AccessSection result = null;
-    // Makse sure the id
-    if (id == null || id.equals(""))
+
+    /* The method to write all access rule into db */
+    private void writeAccessRuleToDB() throws SAXException
     {
-      return result;
-    }
-    // go throught vector and find the list
-    for (int i=0; i<unChangableAccessSubTreeVector.size();i++)
+        //Delete old permssion
+        deletePermissionsInAccessTable(docid);
+        //write top leve access rule
+        writeTopLevelAccessRuleToDB();
+        //write additional access rule
+        //writeAddtionalAccessRuleToDB();
+    }//writeAccessRuleToDB
+
+    /* The method to write top level access rule into db. */
+    private void writeTopLevelAccessRuleToDB() throws SAXException
     {
-      AccessSection accessObj = (AccessSection)
-                                 unChangableAccessSubTreeVector.elementAt(i);
-      if (accessObj.getSubTreeId() != null && 
-         (accessObj.getSubTreeId()).equals(id))
-      {
-        result = accessObj;
-      }//if
-    }//for
-    return result;
-  }//getAccessSectionFromUnchangableAccessVector
-      
-  /* Compare two node stacks to see if they are same */
-  private void comparingNodeStacks(Stack stack1, Stack stack2) 
-                                 throws SAXException
-  {
-    // make sure stack1 and stack2 are not empty
-    if (stack1.isEmpty() || stack2.isEmpty())
+
+        // for top document level
+        Object accessSection = topLevelAccessControlMap.get(docid);
+        boolean top = true;
+        String subSectionId = null;
+        if (accessSection != null) {
+            AccessSection accessSectionObj = (AccessSection) accessSection;
+
+            // if accessSection is not null and is not reference
+            if (accessSectionObj.getReferences() == null) {
+                // write the top level access module into xml_accesssubtree to
+                // store info
+                // and then when update to check if the user can update it or
+                // not
+                deleteAccessSubTreeRecord(docid);
+                writeAccessSubTreeIntoDB(accessSectionObj, TOPLEVEL);
+
+                //write access section into xml_access table
+                writeGivenAccessRuleIntoDB(accessSectionObj, top, subSectionId);
+                // write relative online data file into xml_access too.
+                /*
+                 * for (int i= 0; i <onlineDataFileIdVector.size(); i++) {
+                 * String id = (String)onlineDataFileIdVector.elementAt(i);
+                 * writeAccessRuleForRalatedDataFileIntoDB(accessSectionObj,
+                 * id);
+                 */
+
+            } else {
+
+                // this is a reference and go trough the vector which contains
+                // all
+                // access object
+                String referenceId = accessSectionObj.getReferences();
+                boolean findAccessObject = false;
+                MetaCatUtil.debugMessage("referered id for top access: "
+                        + referenceId, 35);
+                for (int i = 0; i < accessObjectList.size(); i++) {
+                    AccessSection accessObj = (AccessSection) accessObjectList
+                            .elementAt(i);
+                    String accessObjId = accessObj.getSubTreeId();
+                    if (referenceId != null && accessObj != null
+                            && referenceId.equals(accessObjId)) {
+                        // make sure the user didn't change any thing in this
+                        // access moduel
+                        // too if user doesn't have all permission
+                        if (needCheckingAccessModule) {
+
+                            Stack newStack = accessObj.getStoredTmpNodeStack();
+                            //revise order
+                            newStack = MetaCatUtil.reviseStack(newStack);
+                            // go throught the vector of
+                            // unChangableAccessSubtreevector
+                            // and find the one whose id is as same as
+                            // referenceid
+                            AccessSection oldAccessObj = getAccessSectionFromUnchangableAccessVector(referenceId);
+                            //if oldAccessObj is null something is wrong
+                            if (oldAccessObj == null) {
+                                throw new SAXException(UPDATEACCESSERROR);
+                            }//if
+                            else {
+                                // Get the node stack from old access obj
+                                Stack oldStack = oldAccessObj
+                                        .getSubTreeNodeStack();
+                                comparingNodeStacks(newStack, oldStack);
+                            }//else
+                        }//if
+                        // write accessobject into db
+                        writeGivenAccessRuleIntoDB(accessObj, top, subSectionId);
+                        // add access rule for related on line data id too.
+                        /*
+                         * for (int j= 0; j <onlineDataFileIdVector.size();
+                         * j++) { String id =
+                         * (String)onlineDataFileIdVector.elementAt(j);
+                         * writeAccessRuleForRalatedDataFileIntoDB(accessObj,
+                         * id);
+                         */
+
+                        //write the reference access into xml_accesssubtree
+                        // too
+                        // write the top level access module into
+                        // xml_accesssubtree to store info
+                        // and then when update to check if the user can update
+                        // it or not
+                        deleteAccessSubTreeRecord(docid);
+                        writeAccessSubTreeIntoDB(accessSectionObj, TOPLEVEL);
+                        writeAccessSubTreeIntoDB(accessObj, SUBTREELEVEL);
+                        findAccessObject = true;
+                        break;
+                    }
+                }//for
+                // if we couldn't find an access subtree id for this reference
+                // id
+                if (!findAccessObject) { throw new SAXException(
+                        "The referenceid: " + referenceId
+                                + " is not access subtree"); }//if
+            }//else
+
+        }//if
+        else {
+            // couldn't find a access section object
+            MetaCatUtil.debugMessage(
+                    "couldn't find access control for document: " + docid, 35);
+        }
+
+    }//writeTopLevelAccessRuletoDB
+
+    /* Given a subtree id and find the responding access section */
+    private AccessSection getAccessSectionFromUnchangableAccessVector(String id)
     {
-      MetaCatUtil.debugMessage("Because stack is empty!", 35);
-      throw new SAXException(UPDATEACCESSERROR);
-    }
-    // go throw two stacks and compare every element
-    while (!stack1.isEmpty())
+        AccessSection result = null;
+        // Makse sure the id
+        if (id == null || id.equals("")) { return result; }
+        // go throught vector and find the list
+        for (int i = 0; i < unChangableAccessSubTreeVector.size(); i++) {
+            AccessSection accessObj = (AccessSection) unChangableAccessSubTreeVector
+                    .elementAt(i);
+            if (accessObj.getSubTreeId() != null
+                    && (accessObj.getSubTreeId()).equals(id)) {
+                result = accessObj;
+            }//if
+        }//for
+        return result;
+    }//getAccessSectionFromUnchangableAccessVector
+
+    /* Compare two node stacks to see if they are same */
+    private void comparingNodeStacks(Stack stack1, Stack stack2)
+            throws SAXException
     {
-      // Pop an element from stack1
-      NodeRecord record1 = (NodeRecord) stack1.pop();
-      // Pop an element from stack2(stack 2 maybe empty)
-      NodeRecord record2 = null;
-      try
-      {
-        record2 = (NodeRecord) stack2.pop();
-      }
-      catch (EmptyStackException ee)
-      {
-        MetaCatUtil.debugMessage("Node stack2 is empty but stack1 isn't!", 35);
-        throw new SAXException(UPDATEACCESSERROR);
-      }
-      // if two records are not same throw a exception
-      if (!record1.contentEquals(record2))
-      {
-        MetaCatUtil.debugMessage("Two records from new and old stack are not "+
-                                 "same!", 30);
-        throw new SAXException(UPDATEACCESSERROR);
-      }//if
-    }//while
-    
-    // now stack1 is empty and we should make sure stack2 is empty too
-    if(!stack2.isEmpty())
-    {
-      MetaCatUtil.debugMessage("stack2 still have some elements while stack "+
-                               "is empty! ", 30);
-      throw new SAXException(UPDATEACCESSERROR);
-    }//if
- }//comparingNodeStacks
-  
-   /* The method to write addtional access rule into db. */
-  private void writeAddtionalAccessRuleToDB() throws SAXException
-  {
-    
-     PreparedStatement pstmt = null;
-     boolean topLevel =false;
-    // go through the vector which contains the additional access control 
-    //hashtable. Each hashtable has info for one additonalmetadata container 
-   for (int j= 0; j < additionalAccessMapList.size(); j++)
-   {
-     
-     Hashtable accessControlMap = 
-                                (Hashtable)additionalAccessMapList.elementAt(j);
-     // additional access rule
-     Enumeration en = accessControlMap.keys();
-     
-     while(en.hasMoreElements())
-     {
-       try
-       {
-         // Get subsection id
-          String subSectionId = (String)en.nextElement();
-          MetaCatUtil.debugMessage("sub section id in additional access mapping"
-                                   +"(go through): "+ subSectionId, 35);
-          
-          if (subSectionId == null)
-          {
-            // if id is null, terminate the program
-            throw new SAXException("subtree id is null");
-          }
-          // Get AccessSection Object
-          Object accessSectionObj = accessControlMap.get(subSectionId);
-          if (accessSectionObj == null)
-          {
-            // if accesssection is null, terminate the program
-            throw new SAXException("access subtree is null");
-          }
-          else
-          {
-            AccessSection accessControlObj = (AccessSection)accessSectionObj;
-            // if the access section is not references, write it to db
-            if (accessControlObj.getReferences() == null)
-            {
-              writeGivenAccessRuleIntoDB(accessControlObj, topLevel, 
-                                         subSectionId);
+        // make sure stack1 and stack2 are not empty
+        if (stack1.isEmpty() || stack2.isEmpty()) {
+            MetaCatUtil.debugMessage("Because stack is empty!", 35);
+            throw new SAXException(UPDATEACCESSERROR);
+        }
+        // go throw two stacks and compare every element
+        while (!stack1.isEmpty()) {
+            // Pop an element from stack1
+            NodeRecord record1 = (NodeRecord) stack1.pop();
+            // Pop an element from stack2(stack 2 maybe empty)
+            NodeRecord record2 = null;
+            try {
+                record2 = (NodeRecord) stack2.pop();
+            } catch (EmptyStackException ee) {
+                MetaCatUtil.debugMessage(
+                        "Node stack2 is empty but stack1 isn't!", 35);
+                throw new SAXException(UPDATEACCESSERROR);
             }
-            else
-            {
-              // this is a reference and go trough the vector which contains all
-              // access object
-              String referenceId = accessControlObj.getReferences();
-            
-              boolean findAccessObject = false;
-              MetaCatUtil.debugMessage("referered id for additional access "+
-                                     "mapping(go through): "+ referenceId, 35);
-              for (int i=0; i<accessObjectList.size(); i++)
-              {
-                AccessSection accessObj = 
-                                (AccessSection)accessObjectList.elementAt(i);
-                String accessObjId = accessObj.getSubTreeId();
-                MetaCatUtil.debugMessage("access obj id in the list(go through): "
-                                        + accessObjId, 35);
-                if (referenceId != null && accessObj != null &&
-                    referenceId.equals(accessObjId))
-                {
-                  writeGivenAccessRuleIntoDB(accessObj, topLevel, subSectionId);
-                  findAccessObject = true;
-                }//if
-              }//for
-              // if we couldn't find an access subtree id for this reference id
-              if (!findAccessObject)
-              {
-                throw new SAXException("The referenceid: " + referenceId +
-                               " is not access subtree");
-              }//if
-            }//else
-          }//else
-       }//try
-       catch (Exception e)
-       {
-         
-         MetaCatUtil.debugMessage("error in EmlSAXHandler.writeAddtionalAccess"
-                                   + ": "+e.getMessage(), 30);
-         throw new SAXException(e.getMessage());
-       }
-     }//while
-    }//for
-  }//writeAccessRuletoDB
-  
-  /* Write a gaven access rule into db*/
-  private void writeGivenAccessRuleIntoDB(AccessSection accessSection, 
-                                         boolean topLevel, String subSectionId) 
-                                         throws SAXException
-  {
-     if (accessSection == null)
-     {
-       throw new SAXException("The access object is null");
-     }
-     
-      String permOrder = accessSection.getPermissionOrder();
-      String sql = null;
-      PreparedStatement pstmt = null;
-      if (topLevel)
-      {
-        sql = "INSERT INTO xml_access (docid, principal_name, permission, "+
-                 "perm_type, perm_order, accessfileid) VALUES " +
-                 " (?, ?, ?, ?, ?, ?)";
-      }
-      else
-      {
-        sql ="INSERT INTO xml_access (docid,principal_name, "+ 
-             "permission, perm_type, perm_order, accessfileid, subtreeid, "+
-             " startnodeid, endnodeid) VALUES" +
-             " (?, ?, ?, ?, ?, ?, ?, ?, ?)";
-      }
-      try 
-      {
-     
-        pstmt = connection.prepareStatement(sql);
-        // Increase DBConnection usage count
-        connection.increaseUsageCount(1);
-        // Bind the values to the query
-        pstmt.setString(1, docid);
-        MetaCatUtil.debugMessage("Docid in accesstable: "+ docid, 35);
-        pstmt.setString(6, docid);
-        MetaCatUtil.debugMessage("Accessfileid in accesstable: "+ docid, 35);
-        pstmt.setString(5, permOrder);
-        MetaCatUtil.debugMessage("PermOder in accesstable: "+ permOrder, 35);
-        // if it is not top level, set subsection id
-        if (!topLevel)
-        {
-          long startNodeId = 0;
-          long endNodeId = 0;
-          // for subtree should specify the
-          if (subSectionId == null)
-          {
-            throw new SAXException("The subsection is null");
-          }
-          // go through the substree list vector and found the start node id
-          // and stop node id for this subtree id
-          for (int i=0; i<subTreeList.size(); i++)
-          {
-            SubTree tree = (SubTree)subTreeList.elementAt(i);
-            String subTreeId = tree.getSubTreeId();
-            if (subSectionId.equals(subTreeId))
-            {
-              startNodeId = tree.getStartNodeId();
-              endNodeId = tree.getEndNodeId(); 
+            // if two records are not same throw a exception
+            if (!record1.contentEquals(record2)) {
+                MetaCatUtil
+                        .debugMessage(
+                                "Two records from new and old stack are not "
+                                        + "same!", 30);
+                throw new SAXException(UPDATEACCESSERROR);
             }//if
-          }//for
-          if (startNodeId == 0 || endNodeId == 0)
-          {
-            throw new SAXException("Could find the subtree"
-                                   + "for this id: "+subSectionId);
-          }
-          pstmt.setString(7, subSectionId);
-          MetaCatUtil.debugMessage("SubSectionId in accesstable: "+ 
-                                    subSectionId, 35);
-          pstmt.setLong(8, startNodeId);
-          MetaCatUtil.debugMessage("Start node id is: " + startNodeId, 35);
-          pstmt.setLong(9, endNodeId);
-          MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
-          
-        }
-      
-        Vector accessRules = accessSection.getAccessRules();
-        // go through every rule
-        for (int i=0; i<accessRules.size(); i++)
-        {
-          AccessRule rule = (AccessRule)accessRules.elementAt(i);
-          String permType = rule.getPermissionType();
-          int permission = rule.getPermission();
-          pstmt.setInt(3, permission);
-          MetaCatUtil.debugMessage("permission in accesstable: "+ permission, 35);
-          pstmt.setString(4, permType);
-          MetaCatUtil.debugMessage("Permtype in accesstable: "+ permType, 35);
-          // go through every principle in rule
-          Vector nameVector = rule.getPrincipal();
-          for ( int j = 0; j < nameVector.size(); j++ ) 
-          {
-            String prName = (String)nameVector.elementAt(j);
-            pstmt.setString(2, prName);
-            MetaCatUtil.debugMessage("Principal in accesstable: "+prName, 35);
-            pstmt.execute();
-          }//for
+        }//while
+
+        // now stack1 is empty and we should make sure stack2 is empty too
+        if (!stack2.isEmpty()) {
+            MetaCatUtil.debugMessage(
+                    "stack2 still have some elements while stack "
+                            + "is empty! ", 30);
+            throw new SAXException(UPDATEACCESSERROR);
+        }//if
+    }//comparingNodeStacks
+
+    /* The method to write addtional access rule into db. */
+    private void writeAddtionalAccessRuleToDB() throws SAXException
+    {
+
+        PreparedStatement pstmt = null;
+        boolean topLevel = false;
+        // go through the vector which contains the additional access control
+        //hashtable. Each hashtable has info for one additonalmetadata
+        // container
+        for (int j = 0; j < additionalAccessMapList.size(); j++) {
+
+            Hashtable accessControlMap = (Hashtable) additionalAccessMapList
+                    .elementAt(j);
+            // additional access rule
+            Enumeration en = accessControlMap.keys();
+
+            while (en.hasMoreElements()) {
+                try {
+                    // Get subsection id
+                    String subSectionId = (String) en.nextElement();
+                    MetaCatUtil.debugMessage(
+                            "sub section id in additional access mapping"
+                                    + "(go through): " + subSectionId, 35);
+
+                    if (subSectionId == null) { 
+                    // if id is null, terminate the program
+                    throw new SAXException("subtree id is null"); }
+                    // Get AccessSection Object
+                    Object accessSectionObj = accessControlMap
+                            .get(subSectionId);
+                    if (accessSectionObj == null) {
+                        // if accesssection is null, terminate the program
+                        throw new SAXException("access subtree is null");
+                    } else {
+                        AccessSection accessControlObj = (AccessSection) accessSectionObj;
+                        // if the access section is not references, write it to
+                        // db
+                        if (accessControlObj.getReferences() == null) {
+                            writeGivenAccessRuleIntoDB(accessControlObj,
+                                    topLevel, subSectionId);
+                        } else {
+                            // this is a reference and go trough the vector
+                            // which contains all
+                            // access object
+                            String referenceId = accessControlObj
+                                    .getReferences();
+
+                            boolean findAccessObject = false;
+                            MetaCatUtil.debugMessage(
+                                    "referered id for additional access "
+                                            + "mapping(go through): "
+                                            + referenceId, 35);
+                            for (int i = 0; i < accessObjectList.size(); i++) {
+                                AccessSection accessObj = (AccessSection) accessObjectList
+                                        .elementAt(i);
+                                String accessObjId = accessObj.getSubTreeId();
+                                MetaCatUtil.debugMessage(
+                                        "access obj id in the list(go through): "
+                                                + accessObjId, 35);
+                                if (referenceId != null && accessObj != null
+                                        && referenceId.equals(accessObjId)) {
+                                    writeGivenAccessRuleIntoDB(accessObj,
+                                            topLevel, subSectionId);
+                                    findAccessObject = true;
+                                }//if
+                            }//for
+                            // if we couldn't find an access subtree id for
+                            // this reference id
+                            if (!findAccessObject) { throw new SAXException(
+                                    "The referenceid: " + referenceId
+                                            + " is not access subtree"); }//if
+                        }//else
+                    }//else
+                }//try
+                catch (Exception e) {
+
+                    MetaCatUtil.debugMessage(
+                            "error in EmlSAXHandler.writeAddtionalAccess"
+                                    + ": " + e.getMessage(), 30);
+                    throw new SAXException(e.getMessage());
+                }
+            }//while
         }//for
-        pstmt.close();
-      }//try 
-      catch (SQLException e) 
-      {
-        throw new 
-        SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + e.getMessage());
-      }//catch
-      finally
-      {
-        try
-        {
-          pstmt.close();
+    }//writeAccessRuletoDB
+
+    /* Write a gaven access rule into db */
+    private void writeGivenAccessRuleIntoDB(AccessSection accessSection,
+            boolean topLevel, String subSectionId) throws SAXException
+    {
+        if (accessSection == null) { throw new SAXException(
+                "The access object is null"); }
+
+        String permOrder = accessSection.getPermissionOrder();
+        String sql = null;
+        PreparedStatement pstmt = null;
+        if (topLevel) {
+            sql = "INSERT INTO xml_access (docid, principal_name, permission, "
+                    + "perm_type, perm_order, accessfileid) VALUES "
+                    + " (?, ?, ?, ?, ?, ?)";
+        } else {
+            sql = "INSERT INTO xml_access (docid,principal_name, "
+                    + "permission, perm_type, perm_order, accessfileid, subtreeid, "
+                    + " startnodeid, endnodeid) VALUES"
+                    + " (?, ?, ?, ?, ?, ?, ?, ?, ?)";
         }
-        catch(SQLException ee)
-        {
-          throw new 
-          SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + 
-          ee.getMessage());
-        }
-      }//finally
-     
-  }//writeGivenAccessRuleIntoDB
-  
-  
-  
-    /* Write a gaven access rule into db*/
-  private void writeAccessRuleForRalatedDataFileIntoDB
-                  (AccessSection accessSection, String dataId) 
-                                         throws SAXException
-  {
-      if (accessSection == null)
-      {
-        throw new SAXException("The access object is null");
-      }
-      // get rid of rev from dataId
-      dataId = MetaCatUtil.getDocIdFromString(dataId);
-      String permOrder = accessSection.getPermissionOrder();
-      String sql = null;
-      PreparedStatement pstmt = null;
-      sql = "INSERT INTO xml_access (docid, principal_name, permission, "+
-                 "perm_type, perm_order, accessfileid) VALUES " +
-                 " (?, ?, ?, ?, ?, ?)";
-   
-      try 
-      {
-     
-        pstmt = connection.prepareStatement(sql);
-        // Increase DBConnection usage count
-        connection.increaseUsageCount(1);
-        // Bind the values to the query
-        pstmt.setString(1, dataId);
-        MetaCatUtil.debugMessage("Docid in accesstable: "+ docid, 35);
-        pstmt.setString(6, docid);
-        MetaCatUtil.debugMessage("Accessfileid in accesstable: "+ docid, 35);
-        pstmt.setString(5, permOrder);
-        MetaCatUtil.debugMessage("PermOder in accesstable: "+ permOrder, 35);
-        // if it is not top level, set subsection id
-            
-        Vector accessRules = accessSection.getAccessRules();
-        // go through every rule
-        for (int i=0; i<accessRules.size(); i++)
-        {
-          AccessRule rule = (AccessRule)accessRules.elementAt(i);
-          String permType = rule.getPermissionType();
-          int permission = rule.getPermission();
-          pstmt.setInt(3, permission);
-          MetaCatUtil.debugMessage("permission in accesstable: "+ permission, 35);
-          pstmt.setString(4, permType);
-          MetaCatUtil.debugMessage("Permtype in accesstable: "+ permType, 35);
-          // go through every principle in rule
-          Vector nameVector = rule.getPrincipal();
-          for ( int j = 0; j < nameVector.size(); j++ ) 
-          {
-            String prName = (String)nameVector.elementAt(j);
-            pstmt.setString(2, prName);
-            MetaCatUtil.debugMessage("Principal in accesstable: "+prName, 35);
-            pstmt.execute();
-          }//for
-        }//for
-        pstmt.close();
-      }//try 
-      catch (SQLException e) 
-      {
-        throw new 
-        SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + e.getMessage());
-      }//catch
-      finally
-      {
-        try
-        {
-          pstmt.close();
-        }
-        catch(SQLException ee)
-        {
-          throw new 
-          SAXException("EMLSAXHandler.writeAccessRuletoDB(): " + 
-          ee.getMessage());
-        }
-      }//finally
-     
-  }//writeAccessRuleForRalatedDataFileIntoDB
-  
-  
-  
-  
-  
-  /* Delete from db all permission for resources related to @aclid if any.*/
-  private void deletePermissionsInAccessTable(String aclid) 
-          throws SAXException 
-  {
-    Statement stmt = null;
-    try
+        try {
+
+            pstmt = connection.prepareStatement(sql);
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            // Bind the values to the query
+            pstmt.setString(1, docid);
+            MetaCatUtil.debugMessage("Docid in accesstable: " + docid, 35);
+            pstmt.setString(6, docid);
+            MetaCatUtil.debugMessage("Accessfileid in accesstable: " + docid,
+                    35);
+            pstmt.setString(5, permOrder);
+            MetaCatUtil.debugMessage("PermOder in accesstable: " + permOrder,
+                    35);
+            // if it is not top level, set subsection id
+            if (!topLevel) {
+                long startNodeId = 0;
+                long endNodeId = 0;
+                // for subtree should specify the
+                if (subSectionId == null) { throw new SAXException(
+                        "The subsection is null"); }
+                // go through the substree list vector and found the start node
+                // id
+                // and stop node id for this subtree id
+                for (int i = 0; i < subTreeList.size(); i++) {
+                    SubTree tree = (SubTree) subTreeList.elementAt(i);
+                    String subTreeId = tree.getSubTreeId();
+                    if (subSectionId.equals(subTreeId)) {
+                        startNodeId = tree.getStartNodeId();
+                        endNodeId = tree.getEndNodeId();
+                    }//if
+                }//for
+                if (startNodeId == 0 || endNodeId == 0) { throw new SAXException(
+                        "Could find the subtree" + "for this id: "
+                                + subSectionId); }
+                pstmt.setString(7, subSectionId);
+                MetaCatUtil.debugMessage("SubSectionId in accesstable: "
+                        + subSectionId, 35);
+                pstmt.setLong(8, startNodeId);
+                MetaCatUtil
+                        .debugMessage("Start node id is: " + startNodeId, 35);
+                pstmt.setLong(9, endNodeId);
+                MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
+
+            }
+
+            Vector accessRules = accessSection.getAccessRules();
+            // go through every rule
+            for (int i = 0; i < accessRules.size(); i++) {
+                AccessRule rule = (AccessRule) accessRules.elementAt(i);
+                String permType = rule.getPermissionType();
+                int permission = rule.getPermission();
+                pstmt.setInt(3, permission);
+                MetaCatUtil.debugMessage("permission in accesstable: "
+                        + permission, 35);
+                pstmt.setString(4, permType);
+                MetaCatUtil.debugMessage(
+                        "Permtype in accesstable: " + permType, 35);
+                // go through every principle in rule
+                Vector nameVector = rule.getPrincipal();
+                for (int j = 0; j < nameVector.size(); j++) {
+                    String prName = (String) nameVector.elementAt(j);
+                    pstmt.setString(2, prName);
+                    MetaCatUtil.debugMessage("Principal in accesstable: "
+                            + prName, 35);
+                    pstmt.execute();
+                }//for
+            }//for
+            pstmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException("EMLSAXHandler.writeAccessRuletoDB(): "
+                    + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pstmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException("EMLSAXHandler.writeAccessRuletoDB(): "
+                        + ee.getMessage());
+            }
+        }//finally
+
+    }//writeGivenAccessRuleIntoDB
+
+    /* Write a gaven access rule into db */
+    private void writeAccessRuleForRalatedDataFileIntoDB(
+            AccessSection accessSection, String dataId) throws SAXException
     {
-      // delete all acl records for resources related to @aclid if any
-      stmt = connection.createStatement();
-      // Increase DBConnection usage count
-      connection.increaseUsageCount(1);
-      stmt.execute("DELETE FROM xml_access WHERE accessfileid = '" + aclid +
-                   "'"); 
-    
-    }
-    catch (SQLException e)
+        if (accessSection == null) { throw new SAXException(
+                "The access object is null"); }
+        // get rid of rev from dataId
+        dataId = MetaCatUtil.getDocIdFromString(dataId);
+        String permOrder = accessSection.getPermissionOrder();
+        String sql = null;
+        PreparedStatement pstmt = null;
+        sql = "INSERT INTO xml_access (docid, principal_name, permission, "
+                + "perm_type, perm_order, accessfileid) VALUES "
+                + " (?, ?, ?, ?, ?, ?)";
+
+        try {
+
+            pstmt = connection.prepareStatement(sql);
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            // Bind the values to the query
+            pstmt.setString(1, dataId);
+            MetaCatUtil.debugMessage("Docid in accesstable: " + docid, 35);
+            pstmt.setString(6, docid);
+            MetaCatUtil.debugMessage("Accessfileid in accesstable: " + docid,
+                    35);
+            pstmt.setString(5, permOrder);
+            MetaCatUtil.debugMessage("PermOder in accesstable: " + permOrder,
+                    35);
+            // if it is not top level, set subsection id
+
+            Vector accessRules = accessSection.getAccessRules();
+            // go through every rule
+            for (int i = 0; i < accessRules.size(); i++) {
+                AccessRule rule = (AccessRule) accessRules.elementAt(i);
+                String permType = rule.getPermissionType();
+                int permission = rule.getPermission();
+                pstmt.setInt(3, permission);
+                MetaCatUtil.debugMessage("permission in accesstable: "
+                        + permission, 35);
+                pstmt.setString(4, permType);
+                MetaCatUtil.debugMessage(
+                        "Permtype in accesstable: " + permType, 35);
+                // go through every principle in rule
+                Vector nameVector = rule.getPrincipal();
+                for (int j = 0; j < nameVector.size(); j++) {
+                    String prName = (String) nameVector.elementAt(j);
+                    pstmt.setString(2, prName);
+                    MetaCatUtil.debugMessage("Principal in accesstable: "
+                            + prName, 35);
+                    pstmt.execute();
+                }//for
+            }//for
+            pstmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException("EMLSAXHandler.writeAccessRuletoDB(): "
+                    + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pstmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException("EMLSAXHandler.writeAccessRuletoDB(): "
+                        + ee.getMessage());
+            }
+        }//finally
+
+    }//writeAccessRuleForRalatedDataFileIntoDB
+
+    /* Delete from db all permission for resources related to @aclid if any. */
+    private void deletePermissionsInAccessTable(String aclid)
+            throws SAXException
     {
-      throw new SAXException(e.getMessage());
-    }
-    finally
-    {
-      try
-      {
-        stmt.close();
-      }
-      catch (SQLException ee)
-      {
-        throw new SAXException(ee.getMessage());
-      }
-    }
-  }//deletePermissionsInAccessTable
-  
-  
-  /* In order to make sure only usr has "all" permission can update access
-   * subtree in eml document we need to keep access subtree info in 
-   * xml_accesssubtree table, such as docid, version, startnodeid, endnodeid
-   */
-  private void writeAccessSubTreeIntoDB(AccessSection accessSection, 
-                                         String level) 
-                                         throws SAXException
-  {
-     if (accessSection == null)
-     {
-       throw new SAXException("The access object is null");
-     }
-     
-      String sql = null;
-      PreparedStatement pstmt = null;
-      sql = "INSERT INTO xml_accesssubtree (docid, rev, controllevel, "+
-                 "subtreeid, startnodeid, endnodeid) VALUES " +
-                 " (?, ?, ?, ?, ?, ?)";
-      try 
-      {
-     
-        pstmt = connection.prepareStatement(sql);
-        // Increase DBConnection usage count
-        connection.increaseUsageCount(1);
-        long startNodeId = accessSection.getStartNodeId();
-        long endNodeId = accessSection.getEndNodeId();
-        String sectionId = accessSection.getSubTreeId();
-        // Bind the values to the query
-        pstmt.setString(1, docid);
-        MetaCatUtil.debugMessage("Docid in access-subtreetable: "+ docid, 35);
-        pstmt.setString(2, revision );
-        MetaCatUtil.debugMessage("rev in accesssubtreetable: "+ revision, 35);
-        pstmt.setString(3, level);
-        MetaCatUtil.debugMessage("contorl level in access-subtree table: "+
-                                  level, 35);
-        pstmt.setString(4, sectionId);
-        MetaCatUtil.debugMessage("Subtree id in access-subtree table: "+ 
-                                  sectionId, 35);
-        pstmt.setLong(5, startNodeId);
-        MetaCatUtil.debugMessage("Start node id is: " + startNodeId, 35);
-        pstmt.setLong(6, endNodeId);
-        MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
-        pstmt.execute();
-        pstmt.close();
-      }//try 
-      catch (SQLException e) 
-      {
-        throw new 
-        SAXException("EMLSAXHandler.writeAccessSubTreeIntoDB(): " + 
-                      e.getMessage());
-      }//catch
-      finally
-      {
-        try
-        {
-          pstmt.close();
+        Statement stmt = null;
+        try {
+            // delete all acl records for resources related to @aclid if any
+            stmt = connection.createStatement();
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            stmt.execute("DELETE FROM xml_access WHERE accessfileid = '"
+                    + aclid + "'");
+
+        } catch (SQLException e) {
+            throw new SAXException(e.getMessage());
+        } finally {
+            try {
+                stmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException(ee.getMessage());
+            }
         }
-        catch(SQLException ee)
-        {
-          throw new 
-          SAXException("EMLSAXHandler.writeAccessSubTreeIntoDB(): " + 
-          ee.getMessage());
-        }
-      }//finally
-     
-  }//writeAccessSubtreeIntoDB
-  
-   /* Delete every access subtree record from xml_accesssubtree.*/
-  private void deleteAccessSubTreeRecord(String docId) throws SAXException 
-  {
-    Statement stmt = null;
-    try
+    }//deletePermissionsInAccessTable
+
+    /*
+     * In order to make sure only usr has "all" permission can update access
+     * subtree in eml document we need to keep access subtree info in
+     * xml_accesssubtree table, such as docid, version, startnodeid, endnodeid
+     */
+    private void writeAccessSubTreeIntoDB(AccessSection accessSection,
+            String level) throws SAXException
     {
-      // delete all acl records for resources related to @aclid if any
-      stmt = connection.createStatement();
-      // Increase DBConnection usage count
-      connection.increaseUsageCount(1);
-      stmt.execute("DELETE FROM xml_accesssubtree WHERE docid = '" + docId + "'"); 
-   
-    }
-    catch (SQLException e)
+        if (accessSection == null) { throw new SAXException(
+                "The access object is null"); }
+
+        String sql = null;
+        PreparedStatement pstmt = null;
+        sql = "INSERT INTO xml_accesssubtree (docid, rev, controllevel, "
+                + "subtreeid, startnodeid, endnodeid) VALUES "
+                + " (?, ?, ?, ?, ?, ?)";
+        try {
+
+            pstmt = connection.prepareStatement(sql);
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            long startNodeId = accessSection.getStartNodeId();
+            long endNodeId = accessSection.getEndNodeId();
+            String sectionId = accessSection.getSubTreeId();
+            // Bind the values to the query
+            pstmt.setString(1, docid);
+            MetaCatUtil.debugMessage("Docid in access-subtreetable: " + docid,
+                    35);
+            pstmt.setString(2, revision);
+            MetaCatUtil.debugMessage("rev in accesssubtreetable: " + revision,
+                    35);
+            pstmt.setString(3, level);
+            MetaCatUtil.debugMessage("contorl level in access-subtree table: "
+                    + level, 35);
+            pstmt.setString(4, sectionId);
+            MetaCatUtil.debugMessage("Subtree id in access-subtree table: "
+                    + sectionId, 35);
+            pstmt.setLong(5, startNodeId);
+            MetaCatUtil.debugMessage("Start node id is: " + startNodeId, 35);
+            pstmt.setLong(6, endNodeId);
+            MetaCatUtil.debugMessage("End node id is: " + endNodeId, 35);
+            pstmt.execute();
+            pstmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException("EMLSAXHandler.writeAccessSubTreeIntoDB(): "
+                    + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pstmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException(
+                        "EMLSAXHandler.writeAccessSubTreeIntoDB(): "
+                                + ee.getMessage());
+            }
+        }//finally
+
+    }//writeAccessSubtreeIntoDB
+
+    /* Delete every access subtree record from xml_accesssubtree. */
+    private void deleteAccessSubTreeRecord(String docId) throws SAXException
     {
-      throw new SAXException(e.getMessage());
-    }
-    finally
+        Statement stmt = null;
+        try {
+            // delete all acl records for resources related to @aclid if any
+            stmt = connection.createStatement();
+            // Increase DBConnection usage count
+            connection.increaseUsageCount(1);
+            stmt.execute("DELETE FROM xml_accesssubtree WHERE docid = '"
+                    + docId + "'");
+
+        } catch (SQLException e) {
+            throw new SAXException(e.getMessage());
+        } finally {
+            try {
+                stmt.close();
+            } catch (SQLException ee) {
+                throw new SAXException(ee.getMessage());
+            }
+        }
+    }//deleteAccessSubTreeRecord
+
+    // open a file writer for writing inline data to file
+    private FileWriter createInlineDataFileWriter(String fileName)
+            throws SAXException
     {
-      try
-      {
-        stmt.close();
-      }
-      catch (SQLException ee)
-      {
-        throw new SAXException(ee.getMessage());
-      }
+        FileWriter writer = null;
+        String path = MetaCatUtil.getOption("inlinedatafilepath");
+        /*
+         * File inlineDataDirectory = new File(path);
+         */
+        String newFile = path + "/" + fileName;
+        MetaCatUtil.debugMessage("inline file name: " + newFile, 30);
+        try {
+            // true means append
+            writer = new FileWriter(newFile, true);
+        } catch (IOException ioe) {
+            throw new SAXException(ioe.getMessage());
+        }
+        return writer;
     }
-  }//deleteAccessSubTreeRecord
-  
-  // open a file writer for writing inline data to file
-  private FileWriter createInlineDataFileWriter(String fileName) 
-                                               throws SAXException
-  {
-    FileWriter writer = null;
-    String path = MetaCatUtil.getOption("inlinedatafilepath");
-    /*File inlineDataDirectory = new File(path);
-    File newFile = new File(inlineDataDirectory, fileName);*/
-    String newFile = path + "/" + fileName;
-    MetaCatUtil.debugMessage("inline file name: "+newFile, 30);
-    try
+
+    // write inline data into file system and return file name(without path)
+    private void writeInlineDataIntoFile(FileWriter writer, StringBuffer data)
+            throws SAXException
     {
-      // true means append
-      writer = new FileWriter(newFile, true);
+        try {
+            writer.write(data.toString());
+            writer.flush();
+        } catch (Exception e) {
+            throw new SAXException(e.getMessage());
+        }
     }
-    catch (IOException ioe)
+
+    /*
+     * In eml2, the inline data wouldn't store in db, it store in file system
+     * The db stores file name(without path). We got the old file name from db
+     * and compare to the new in line data file
+     */
+    public boolean compareInlineDataFiles(String oldFileName, String newFileName)
+            throws McdbException
     {
-      throw new SAXException(ioe.getMessage());
+        // this method need to be testing
+        boolean same = true;
+        String data = null;
+        String path = MetaCatUtil.getOption("inlinedatafilepath");
+        // the new file name will look like path/docid.rev.2
+        File inlineDataDirectory = new File(path);
+        File oldDataFile = new File(inlineDataDirectory, oldFileName);
+        File newDataFile = new File(inlineDataDirectory, newFileName);
+        try {
+            FileReader oldFileReader = new FileReader(oldDataFile);
+            BufferedReader oldStringReader = new BufferedReader(oldFileReader);
+            FileReader newFileReader = new FileReader(newDataFile);
+            BufferedReader newStringReader = new BufferedReader(newFileReader);
+            // read first line of data
+            String oldString = oldStringReader.readLine();
+            String newString = newStringReader.readLine();
+
+            // at the end oldstring will be null
+            while (oldString != null) {
+                oldString = oldStringReader.readLine();
+                newString = newStringReader.readLine();
+                if (!oldString.equals(newString)) {
+                    same = false;
+                    break;
+                }
+            }
+
+            // if oldString is null but newString is not null, they are same
+            if (same) {
+                if (newString != null) {
+                    same = false;
+                }
+            }
+
+        } catch (Exception e) {
+            throw new McdbException(e.getMessage());
+        }
+        MetaCatUtil.debugMessage("the inline data retrieve from file: " + data,
+                50);
+        return same;
     }
-    return writer;
-  }
-  // write inline data into file system and return file name(without path)
-  private void writeInlineDataIntoFile(FileWriter writer, 
-                                               StringBuffer data) 
-                                               throws SAXException
-  {
-    try
+
+    // if xml file failed to upload, we need to call this method to delete
+    // the inline data already in file system
+    public void deleteInlineFiles()
     {
-      writer.write(data.toString());
-      writer.flush();
+        if (!inlineFileIDList.isEmpty()) {
+            for (int i = 0; i < inlineFileIDList.size(); i++) {
+                String fileName = (String) inlineFileIDList.elementAt(i);
+                deleteInlineDataFile(fileName);
+            }
+        }
     }
-    catch (Exception e)
+
+    /* delete the inline data file */
+    private void deleteInlineDataFile(String fileName)
     {
-      throw new SAXException(e.getMessage());
+
+        String path = MetaCatUtil.getOption("inlinedatafilepath");
+        File inlineDataDirectory = new File(path);
+        File newFile = new File(inlineDataDirectory, fileName);
+        newFile.delete();
+
     }
-  }
-  
-  /* In eml2, the inline data wouldn't store in db, it store in file system
-   * The db stores file name(without path). We got the old file name from db
-   * and compare to the new in line data file
-   */
-  public boolean compareInlineDataFiles(String oldFileName, String newFileName)
-                                                throws McdbException
-  {
-    // this method need to be testing
-    boolean same = true;
-    String data = null;
-    String path = MetaCatUtil.getOption("inlinedatafilepath");
-    // the new file name will look like path/docid.rev.2
-    File inlineDataDirectory = new File(path);
-    File oldDataFile = new File(inlineDataDirectory, oldFileName);
-    File newDataFile = new File(inlineDataDirectory, newFileName);
-    try
+
+    /*
+     * In eml2, the inline data wouldn't store in db, it store in file system
+     * The db stores file name(without path).
+     */
+    public static Reader readInlineDataFromFileSystem(String fileName)
+            throws McdbException
     {
-      FileReader oldFileReader = new FileReader(oldDataFile);
-      BufferedReader oldStringReader = new BufferedReader(oldFileReader);
-      FileReader newFileReader = new FileReader(newDataFile);
-      BufferedReader newStringReader = new BufferedReader(newFileReader);
-      // read first line of data
-      String oldString = oldStringReader.readLine();
-      String newString = newStringReader.readLine();
-     
-      // at the end oldstring will be null
-      while (oldString != null)
-      {
-        oldString = oldStringReader.readLine();
-        newString = newStringReader.readLine();
-        if (!oldString.equals(newString))
-        {
-          same = false;
-          break;
+        //BufferedReader stringReader = null;
+        FileReader fileReader = null;
+        String path = MetaCatUtil.getOption("inlinedatafilepath");
+        // the new file name will look like path/docid.rev.2
+        File inlineDataDirectory = new File(path);
+        File dataFile = new File(inlineDataDirectory, fileName);
+        try {
+            fileReader = new FileReader(dataFile);
+            //stringReader = new BufferedReader(fileReader);
+        } catch (Exception e) {
+            throw new McdbException(e.getMessage());
         }
-      }
-      
-      // if oldString is null but newString is not null, they are same
-      if (same)
-      {
-         if (newString != null)
-         {
-           same = false;
-         }
-      }
-      
+        // return stringReader;
+        return fileReader;
     }
-    catch (Exception e)
+
+    /* Delete relations */
+    private void deleteRelations() throws SAXException
     {
-      throw new McdbException(e.getMessage());
+        PreparedStatement pStmt = null;
+        String sql = "DELETE FROM xml_relation where docid =?";
+        try {
+            pStmt = connection.prepareStatement(sql);
+            //bind variable
+            pStmt.setString(1, docid);
+            //execute query
+            pStmt.execute();
+            pStmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException("EMLSAXHandler.deleteRelations(): "
+                    + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pStmt.close();
+            }//try
+            catch (SQLException ee) {
+                throw new SAXException("EMLSAXHandler.deleteRelations: "
+                        + ee.getMessage());
+            }//catch
+        }//finally
     }
-    MetaCatUtil.debugMessage("the inline data retrieve from file: "+data, 50);
-    return same;
-  }
-  
-  // if xml file failed to upload, we need to call this method to delete
-  // the inline data already in file system
-  public void deleteInlineFiles()
-  {
-     if (!inlineFileIDList.isEmpty())
-     {
-       for ( int i=0; i<inlineFileIDList.size(); i++)
-       {
-         String fileName = (String) inlineFileIDList.elementAt(i);
-         deleteInlineDataFile(fileName);
-       }
-     }
-  }
-  
-  /* delete the inline data file */
-  private void deleteInlineDataFile(String fileName)
-  {
-    
-     String path = MetaCatUtil.getOption("inlinedatafilepath");
-     File inlineDataDirectory = new File(path);
-     File newFile = new File(inlineDataDirectory, fileName);
-     newFile.delete();
-  
-  }
-  
-   /* In eml2, the inline data wouldn't store in db, it store in file system
-   * The db stores file name(without path).
-   */
-  public static Reader readInlineDataFromFileSystem(String fileName) 
-                                              throws McdbException
-  {
-    //BufferedReader stringReader = null;
-    FileReader fileReader = null;
-    String path = MetaCatUtil.getOption("inlinedatafilepath");
-    // the new file name will look like path/docid.rev.2
-    File inlineDataDirectory = new File(path);
-    File dataFile = new File(inlineDataDirectory, fileName);
-    try
+
+    /* Write an online data file id into xml_relation table */
+    private void writeOnlineDataFileIdIntoRelationTable(String dataId)
+            throws SAXException
     {
-      fileReader = new FileReader(dataFile);
-      //stringReader = new BufferedReader(fileReader);
-    }
-    catch (Exception e)
-    {
-      throw new McdbException(e.getMessage());
-    }
-   // return stringReader;
-   return fileReader;
-  }
-  
-  /* Delete relations */
-  private void deleteRelations() throws SAXException
-  {
-    PreparedStatement pStmt = null;
-    String sql = "DELETE FROM xml_relation where docid =?";
-    try
-    {
-      pStmt = connection.prepareStatement(sql);
-      //bind variable
-      pStmt.setString(1, docid);
-      //execute query
-      pStmt.execute();
-      pStmt.close();
-    }//try
-    catch (SQLException e) 
-    {
-       throw new 
-       SAXException("EMLSAXHandler.deleteRelations(): " + 
-                      e.getMessage());
-    }//catch
-    finally
-    {
-      try
-      {
-        pStmt.close();
-      }//try
-      catch(SQLException ee)
-      {
-        throw new 
-        SAXException("EMLSAXHandler.deleteRelations: " + 
-        ee.getMessage());
-      }//catch
-    }//finally
-  }
-  
-  /* Write an online data file id into xml_relation table*/
-  private void writeOnlineDataFileIdIntoRelationTable(String dataId) 
-                                                        throws SAXException
-  {
-    // Get rid of rev
-    dataId = MetaCatUtil.getDocIdFromString(dataId);
-    PreparedStatement pStmt = null;
-    String sql = "INSERT into xml_relation (docid, packagetype, subject, "+
-                 "relationship, object) values (?, ?, ?, ?, ?)";
-    try
-    {
-      pStmt = connection.prepareStatement(sql);
-      //bind variable
-      pStmt.setString(1, docid);
-      pStmt.setString(2, DocumentImpl.EMLNAMESPACE);
-      pStmt.setString(3, docid);
-      pStmt.setString(4, RELATION);
-      pStmt.setString(5, dataId);
-      //execute query
-      pStmt.execute();
-      pStmt.close();
-    }//try
-    catch (SQLException e) 
-    {
-       throw new 
-       SAXException("EMLSAXHandler.writeOnlineDataFileIdIntoRelationTable(): " + 
-                      e.getMessage());
-    }//catch
-    finally
-    {
-      try
-      {
-        pStmt.close();
-      }//try
-      catch(SQLException ee)
-      {
-        throw new 
-        SAXException("EMLSAXHandler.writeOnlineDataFileIdIntoRelationTable(): " + 
-        ee.getMessage());
-      }//catch
-    }//finally
-    
-  }//writeOnlineDataFileIdIntoRelationTable
-  
- 
+        // Get rid of rev
+        dataId = MetaCatUtil.getDocIdFromString(dataId);
+        PreparedStatement pStmt = null;
+        String sql = "INSERT into xml_relation (docid, packagetype, subject, "
+                + "relationship, object) values (?, ?, ?, ?, ?)";
+        try {
+            pStmt = connection.prepareStatement(sql);
+            //bind variable
+            pStmt.setString(1, docid);
+            pStmt.setString(2, DocumentImpl.EMLNAMESPACE);
+            pStmt.setString(3, docid);
+            pStmt.setString(4, RELATION);
+            pStmt.setString(5, dataId);
+            //execute query
+            pStmt.execute();
+            pStmt.close();
+        }//try
+        catch (SQLException e) {
+            throw new SAXException(
+                    "EMLSAXHandler.writeOnlineDataFileIdIntoRelationTable(): "
+                            + e.getMessage());
+        }//catch
+        finally {
+            try {
+                pStmt.close();
+            }//try
+            catch (SQLException ee) {
+                throw new SAXException(
+                        "EMLSAXHandler.writeOnlineDataFileIdIntoRelationTable(): "
+                                + ee.getMessage());
+            }//catch
+        }//finally
+
+    }//writeOnlineDataFileIdIntoRelationTable
+
 }
