Project

General

Profile

« Previous | Next » 

Revision 2169

Added by sgarg over 20 years ago

Made initial changes for accepting EML version 2.1.0 in Metacat

View differences:

src/edu/ucsb/nceas/metacat/MetacatReplication.java
549 549
      String parserBase = null;
550 550
      // this for eml2 and we need user eml2 parser
551 551
      if (docType != null && 
552
          (docType.trim()).equals(DocumentImpl.EMLNAMESPACE))
552
          (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
553 553
      {
554 554
         MetaCatUtil.debugMessage("This is an eml2 document!", 30);
555 555
         parserBase = DocumentImpl.EML200;
src/edu/ucsb/nceas/metacat/MetaCatServlet.java
68 68

  
69 69
/**
70 70
 * A metadata catalog server implemented as a Java Servlet
71
 * 
71
 *
72 72
 * <p>
73 73
 * Valid parameters are: <br>
74 74
 * action=query -- query the values of all elements and attributes and return a
......
412 412
                }
413 413
            } else if (action.equals("export")) {
414 414

  
415
                handleExportAction(params, response, username, 
415
                handleExportAction(params, response, username,
416 416
                        groupnames, password);
417 417
            } else if (action.equals("read")) {
418 418
                handleReadAction(params, request, response, username, password,
......
649 649
    // SQUERY & QUERY SECTION
650 650
    /**
651 651
     * Retreive the squery xml, execute it and display it
652
     * 
652
     *
653 653
     * @param out the output stream to the client
654 654
     * @param params the Hashtable of parameters that should be included in the
655 655
     *            squery.
......
671 671

  
672 672
    /**
673 673
     * Create the xml query, execute it and display the results.
674
     * 
674
     *
675 675
     * @param out the output stream to the client
676 676
     * @param params the Hashtable of parameters that should be included in the
677 677
     *            squery.
......
701 701
    //Exoport section
702 702
    /**
703 703
     * Handle the "export" request of data package from Metacat in zip format
704
     * 
704
     *
705 705
     * @param params the Hashtable of HTTP request parameters
706 706
     * @param response the HTTP response object linked to the client
707 707
     * @param user the username sent the request
708 708
     * @param groups the user's groupnames
709 709
     */
710
    private void handleExportAction(Hashtable params, 
711
            HttpServletResponse response, 
710
    private void handleExportAction(Hashtable params,
711
            HttpServletResponse response,
712 712
            String user, String[] groups, String passWord)
713 713
    {
714 714
        // Output stream
......
791 791
     * In eml2 document, the xml can have inline data and data was stripped off
792 792
     * and store in file system. This action can be used to read inline data
793 793
     * only
794
     * 
794
     *
795 795
     * @param params the Hashtable of HTTP request parameters
796 796
     * @param response the HTTP response object linked to the client
797 797
     * @param user the username sent the request
798 798
     * @param groups the user's groupnames
799 799
     */
800 800
    private void handleReadInlineDataAction(Hashtable params,
801
            HttpServletRequest request, HttpServletResponse response, 
801
            HttpServletRequest request, HttpServletResponse response,
802 802
            String user, String passWord, String[] groups)
803 803
    {
804 804
        String[] docs = new String[10];
......
814 814
            // Get the docid
815 815
            inlineDataId = docs[0];
816 816
            // Make sure the client specify docid
817
            if (inlineDataId == null || inlineDataId.equals("")) { 
817
            if (inlineDataId == null || inlineDataId.equals("")) {
818 818
                throw new Exception("You didn't specify requested inlinedataid"); }
819 819

  
820 820
            // check for permission
......
828 828
                        + " doesn't have permission " + " to read document "
829 829
                        + docId);
830 830
            } else if (controller.hasSubTreeAccessControl()) {
831
                // if the document has subtree control, we need to check 
831
                // if the document has subtree control, we need to check
832 832
                // subtree control
833 833
                // get node id for inlinedata
834 834
                long nodeId = getInlineDataNodeId(inlineDataId, docId);
835 835
                if (!controller.hasPermissionForSubTreeNode(user, groups,
836
                    AccessControlInterface.READSTRING, nodeId)) { 
836
                    AccessControlInterface.READSTRING, nodeId)) {
837 837
                    throw new Exception(
838 838
                    "User " + user + " doesn't have permission "
839
                    + " to read inlinedata " + inlineDataId); 
839
                    + " to read inlinedata " + inlineDataId);
840 840
                }
841 841
            }
842 842

  
......
854 854
            }
855 855
            out.close();
856 856

  
857
            EventLog.getInstance().log(request.getRemoteAddr(), user, 
857
            EventLog.getInstance().log(request.getRemoteAddr(), user,
858 858
                    inlineDataId, "readinlinedata");
859 859
        } catch (Exception e) {
860 860
            try {
......
941 941
     * Handle the "read" request of metadata/data files from Metacat or any
942 942
     * files from Internet; transformed metadata XML document into HTML
943 943
     * presentation if requested; zip files when more than one were requested.
944
     * 
944
     *
945 945
     * @param params the Hashtable of HTTP request parameters
946 946
     * @param request the HTTP request object linked to the client
947 947
     * @param response the HTTP response object linked to the client
......
1014 1014
                            readFromURLConnection(response, docid);
1015 1015
                        }
1016 1016
                    }
1017
                    
1017

  
1018 1018
                } catch (MalformedURLException mue) {
1019 1019
                    docid = docs[i];
1020 1020
                    if (zip) {
1021 1021
                        addDocToZip(request, docid, zout, user, groups);
1022 1022
                    } else {
1023
                        readFromMetacat(request, response, docid, qformat, 
1024
                                abstrpath, user, groups, zip, zout, 
1023
                        readFromMetacat(request, response, docid, qformat,
1024
                                abstrpath, user, groups, zip, zout,
1025 1025
                                withInlineData, params);
1026 1026
                    }
1027 1027
                }
......
1136 1136
        }
1137 1137
    }
1138 1138

  
1139
    /** read metadata or data from Metacat 
1139
    /** read metadata or data from Metacat
1140 1140
     */
1141
    private void readFromMetacat(HttpServletRequest request, 
1141
    private void readFromMetacat(HttpServletRequest request,
1142 1142
            HttpServletResponse response, String docid, String qformat,
1143 1143
            String abstrpath, String user, String[] groups, boolean zip,
1144 1144
            ZipOutputStream zout, boolean withInlineData, Hashtable params)
......
1196 1196
                } finally {
1197 1197
                    if (fin != null) fin.close();
1198 1198
                }
1199
                
1199

  
1200 1200
            } else {
1201 1201
                // this is metadata doc
1202 1202
                if (qformat.equals("xml")) {
......
1219 1219
                }
1220 1220

  
1221 1221
            }
1222
            EventLog.getInstance().log(request.getRemoteAddr(), user, 
1222
            EventLog.getInstance().log(request.getRemoteAddr(), user,
1223 1223
                    docid, "read");
1224 1224
        } catch (Exception except) {
1225 1225
            throw except;
1226 1226
        }
1227 1227
    }
1228 1228

  
1229
    /** 
1230
     * read data from URLConnection 
1229
    /**
1230
     * read data from URLConnection
1231 1231
     */
1232 1232
    private void readFromURLConnection(HttpServletResponse response,
1233 1233
            String docid) throws IOException, MalformedURLException
......
1276 1276

  
1277 1277
    }
1278 1278

  
1279
    /** 
1279
    /**
1280 1280
     * read file/doc and write to ZipOutputStream
1281
     * 
1281
     *
1282 1282
     * @param docid
1283 1283
     * @param zout
1284 1284
     * @param user
......
1289 1289
     * @throws McdbException
1290 1290
     * @throws Exception
1291 1291
     */
1292
    private void addDocToZip(HttpServletRequest request, String docid, 
1292
    private void addDocToZip(HttpServletRequest request, String docid,
1293 1293
            ZipOutputStream zout, String user, String[] groups) throws
1294 1294
            ClassNotFoundException, IOException, SQLException, McdbException,
1295 1295
            Exception
......
1365 1365
                    zout.write(bytestring, 0, bytestring.length);
1366 1366
                    zout.closeEntry();
1367 1367
                }
1368
                EventLog.getInstance().log(request.getRemoteAddr(), user, 
1368
                EventLog.getInstance().log(request.getRemoteAddr(), user,
1369 1369
                        docid, "read");
1370 1370
            } catch (Exception except) {
1371 1371
                throw except;
......
1449 1449
                    documentWrapper = new DocumentImplWrapper(rule, validate);
1450 1450
                } else if (needSchemaValidation(xml)) {
1451 1451
                    // for eml2
1452
                    if (needEml2Validation(xml)) {
1452
                    String namespace = findNamespace(xml);
1453
                    if (namespace.compareTo(DocumentImpl.EML2_0_0NAMESPACE)
1454
                                == 0) {
1453 1455
                        // set eml2 base validation parser
1454 1456
                        String rule = DocumentImpl.EML200;
1455 1457
                        // using emlparser to check id validation
1456 1458
                        EMLParser parser = new EMLParser(doctext[0]);
1457 1459
                        documentWrapper = new DocumentImplWrapper(rule, true);
1460
                    } else if (namespace.compareTo(
1461
                                DocumentImpl.EML2_1_0NAMESPACE) == 0) {
1462
                        // set eml2 base validation parser
1463
                        String rule = DocumentImpl.EML210;
1464
                        // using emlparser to check id validation
1465
                        EMLParser parser = new EMLParser(doctext[0]);
1466
                        documentWrapper = new DocumentImplWrapper(rule, true);
1458 1467
                    } else {
1459 1468
                        // set schema base validation parser
1460 1469
                        String rule = DocumentImpl.SCHEMA;
......
1491 1500
                        }
1492 1501
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1493 1502
                                doAction, accNumber, user, groups);
1494
                        EventLog.getInstance().log(request.getRemoteAddr(), 
1503
                        EventLog.getInstance().log(request.getRemoteAddr(),
1495 1504
                                user, accNumber, action[0]);
1496 1505
                    } catch (NullPointerException npe) {
1497 1506
                        newdocid = documentWrapper.write(dbConn, xml, pub, dtd,
1498 1507
                                doAction, null, user, groups);
1499
                        EventLog.getInstance().log(request.getRemoteAddr(), 
1508
                        EventLog.getInstance().log(request.getRemoteAddr(),
1500 1509
                                user, "", action[0]);
1501 1510
                    }
1502 1511
                }
......
1617 1626
    }
1618 1627

  
1619 1628
    /* check if the xml string contains key words to specify schema loocation */
1620
    private boolean needEml2Validation(StringReader xml) throws IOException
1629
    private String findNamespace(StringReader xml) throws IOException
1621 1630
    {
1622
        boolean needEml2Validate = false;
1623
        String emlNameSpace = DocumentImpl.EMLNAMESPACE;
1624
        String schemaLocationContent = null;
1631
        String namespace = null;
1632

  
1633
        String eml2_0_0NameSpace = DocumentImpl.EML2_0_0NAMESPACE;
1634
        String eml2_1_0NameSpace = DocumentImpl.EML2_1_0NAMESPACE;
1635

  
1625 1636
        if (xml == null) {
1626 1637
            MetaCatUtil.debugMessage("Validation for schema is "
1627
                    + needEml2Validate, 10);
1628
            return needEml2Validate;
1638
                    + namespace, 10);
1639
            return namespace;
1629 1640
        }
1630 1641
        String targetLine = getSchemaLine(xml);
1631 1642

  
......
1653 1664
            schemaLocation = targetLine.substring(start + 1, end);
1654 1665
            MetaCatUtil.debugMessage("schemaLocation in xml is: "
1655 1666
                    + schemaLocation, 30);
1656
            if (schemaLocation.indexOf(emlNameSpace) != -1) {
1657
                needEml2Validate = true;
1667
            if (schemaLocation.indexOf(eml2_0_0NameSpace) != -1) {
1668
                namespace = eml2_0_0NameSpace;
1669
            } else if (schemaLocation.indexOf(eml2_1_0NameSpace) != -1) {
1670
                namespace = eml2_1_0NameSpace;
1658 1671
            }
1659 1672
        }
1660 1673

  
1661
        MetaCatUtil.debugMessage("Validation for eml is " + needEml2Validate,
1674
        MetaCatUtil.debugMessage("Validation for eml is " + namespace,
1662 1675
                10);
1663
        return needEml2Validate;
1676
        return namespace;
1664 1677

  
1665 1678
    }
1666 1679

  
......
1720 1733
     * database connection
1721 1734
     */
1722 1735
    private void handleDeleteAction(PrintWriter out, Hashtable params,
1723
            HttpServletRequest request, HttpServletResponse response, 
1736
            HttpServletRequest request, HttpServletResponse response,
1724 1737
            String user, String[] groups)
1725 1738
    {
1726 1739

  
......
1734 1747
            // BEFORE ACCESSING ARRAY
1735 1748
            try {
1736 1749
                DocumentImpl.delete(docid[0], user, groups);
1737
                EventLog.getInstance().log(request.getRemoteAddr(), 
1750
                EventLog.getInstance().log(request.getRemoteAddr(),
1738 1751
                    user, docid[0], "delete");
1739 1752
                response.setContentType("text/xml");
1740 1753
                out.println("<?xml version=\"1.0\"?>");
......
1997 2010
    /**
1998 2011
     * Print a report from the event log based on filter parameters passed in
1999 2012
     * from the web.
2000
     * 
2013
     *
2001 2014
     * TODO: make sure urlencoding of timestamp params is working
2002
     * 
2015
     *
2003 2016
     * @param params the parameters from the web request
2004 2017
     * @param request the http request object for getting request details
2005 2018
     * @param response the http response object for writing output
......
2035 2048
        } catch (ParseException e) {
2036 2049
            System.out.println("Failed to created Timestamp from input.");
2037 2050
        }
2038
        
2051

  
2039 2052
        // Request the report by passing the filter parameters
2040 2053
        try {
2041 2054
            response.setContentType("text/xml");
2042 2055
            PrintWriter out = response.getWriter();
2043
            out.println(EventLog.getInstance().getReport(ipAddress, principal, 
2056
            out.println(EventLog.getInstance().getReport(ipAddress, principal,
2044 2057
                    docid, event, startDate, endDate));
2045 2058
            out.close();
2046 2059
        } catch (IOException e) {
2047 2060
            MetaCatUtil.debugMessage(
2048
                    "Could not open http response for writing: " 
2061
                    "Could not open http response for writing: "
2049 2062
                    + e.getMessage(), 5);
2050 2063
        }
2051 2064
    }
2052
    
2065

  
2053 2066
    /**
2054 2067
     * Handle documents passed to metacat that are encoded using the
2055 2068
     * "multipart/form-data" mime type. This is typically used for uploading
......
2226 2239
                        File newFile = new File(dataDirectory, docid);
2227 2240
                        long size = filePart.writeTo(newFile);
2228 2241

  
2229
                        EventLog.getInstance().log(request.getRemoteAddr(), 
2242
                        EventLog.getInstance().log(request.getRemoteAddr(),
2230 2243
                                username, docid, "upload");
2231 2244
                        // Force replication this data file
2232 2245
                        // To data file, "insert" and update is same
src/edu/ucsb/nceas/metacat/DocumentImpl.java
69 69
   public static final String SCHEMA                 = "Schema";
70 70
   public static final String DTD                    = "DTD";
71 71
   public static final String EML200                 = "eml200";
72
   public static final String EML210                 = "eml210";
72 73
   public static final String EXTERNALSCHEMALOCATIONPROPERTY =
73 74
              "http://apache.org/xml/properties/schema/external-schemaLocation";
74 75
   /*public static final String EXTERNALSCHEMALOCATION =
......
86 87
                              "http://xml.org/sax/features/namespaces";
87 88
   public static final String NAMESPACEPREFIXESFEATURE =
88 89
                              "http://xml.org/sax/features/namespace-prefixes";
89
   public static final String EMLNAMESPACE =
90
                                         MetaCatUtil.getOption("eml2namespace");
90
   public static final String EML2_1_0NAMESPACE =
91
                                         MetaCatUtil.getOption("eml2_1_0namespace");
91 92
                                         // "eml://ecoinformatics.org/eml-2.0.0";
93
   public static final String EML2_0_0NAMESPACE =
94
                                         MetaCatUtil.getOption("eml2_0_0namespace");
95
                                         // "eml://ecoinformatics.org/eml-2.0.0";
92 96

  
97

  
93 98
  public static final String DOCNAME = "docname";
94 99
  public static final String PUBLICID = "publicid";
95 100
  public static final String SYSTEMID = "systemid";
......
858 863
    String dbPublicID = null;
859 864
    String dbSystemID = null;
860 865

  
861
    if (doctype != null && doctype.equals(EMLNAMESPACE))
866
    if (doctype != null && doctype.equals(EML2_0_0NAMESPACE))
862 867
    {
863 868
      proccessEml2 = true;
864 869
    }
......
2331 2336
      parser = XMLReaderFactory.createXMLReader(parserName);
2332 2337
      if (ruleBase != null && ruleBase.equals(EML200))
2333 2338
      {
2334
        MetaCatUtil.debugMessage("eml 2 parser", 20);
2339
        MetaCatUtil.debugMessage("eml 2.0.0 parser", 20);
2335 2340
        chandler = new Eml200SAXHandler(dbconn, action,
2336 2341
                                    docid, rev, user, groups, pub, serverCode);
2337 2342
        parser.setContentHandler((ContentHandler)chandler);
......
2354 2359
            parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
2355 2360
                             externalSchemaLocation);
2356 2361
        }
2362
      } else if (ruleBase != null && ruleBase.equals(EML210))
2363
      {
2364
        MetaCatUtil.debugMessage("eml 2.1.0 parser", 20);
2365
        chandler = new Eml210SAXHandler(dbconn, action,
2366
                                    docid, rev, user, groups, pub, serverCode);
2367
        parser.setContentHandler((ContentHandler)chandler);
2368
        parser.setErrorHandler((ErrorHandler)chandler);
2369
        parser.setProperty(DECLARATIONHANDLERPROPERTY, chandler);
2370
        parser.setProperty(LEXICALPROPERTY, chandler);
2371
        // turn on schema validation feature
2372
        parser.setFeature(VALIDATIONFEATURE, true);
2373
        parser.setFeature(NAMESPACEFEATURE, true);
2374
        //parser.setFeature(NAMESPACEPREFIXESFEATURE, true);
2375
        parser.setFeature(SCHEMAVALIDATIONFEATURE, true);
2376
        // From DB to find the register external schema location
2377
        String externalSchemaLocation = null;
2378
        SchemaLocationResolver resolver = new SchemaLocationResolver();
2379
        externalSchemaLocation = resolver.getNameSpaceAndLocationString();
2380
        // Set external schemalocation.
2381
        if (externalSchemaLocation != null &&
2382
            !(externalSchemaLocation.trim()).equals(""))
2383
        {
2384
            parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
2385
                             externalSchemaLocation);
2386
        }
2357 2387
      }
2358 2388
      else
2359 2389
      {
src/edu/ucsb/nceas/metacat/ReplicationHandler.java
413 413
           
414 414
      String parserBase = null;
415 415
      // this for eml2 and we need user eml2 parser
416
      if (docType != null && (docType.trim()).equals(DocumentImpl.EMLNAMESPACE))
416
      if (docType != null && (docType.trim()).equals(DocumentImpl.EML2_0_0NAMESPACE))
417 417
      {
418 418
         parserBase = DocumentImpl.EML200;
419 419
      }
src/edu/ucsb/nceas/metacat/Eml200SAXHandler.java
2151 2151
            pStmt = connection.prepareStatement(sql);
2152 2152
            //bind variable
2153 2153
            pStmt.setString(1, docid);
2154
            pStmt.setString(2, DocumentImpl.EMLNAMESPACE);
2154
            pStmt.setString(2, DocumentImpl.EML2_0_0NAMESPACE);
2155 2155
            pStmt.setString(3, docid);
2156 2156
            pStmt.setString(4, RELATION);
2157 2157
            pStmt.setString(5, dataId);
src/edu/ucsb/nceas/metacat/Eml210SAXHandler.java
1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that handles the SAX XML events as they
4
 *             are generated from XML documents
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Matt Jones, Jivka Bojilova
8
 *    Release: @release@
9
 *
10
 *   '$Author$'
11
 *     '$Date$'
12
 * '$Revision$'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

  
29
package edu.ucsb.nceas.metacat;
30

  
31
import java.io.BufferedReader;
32
import java.io.File;
33
import java.io.FileReader;
34
import java.io.FileWriter;
35
import java.io.IOException;
36
import java.io.Reader;
37
import java.sql.PreparedStatement;
38
import java.sql.ResultSet;
39
import java.sql.SQLException;
40
import java.sql.Statement;
41
import java.util.EmptyStackException;
42
import java.util.Enumeration;
43
import java.util.Hashtable;
44
import java.util.Stack;
45
import java.util.Vector;
46

  
47
import org.xml.sax.Attributes;
48
import org.xml.sax.SAXException;
49

  
50
/**
51
 * A database aware Class implementing callback bethods for the SAX parser to
52
 * call when processing the XML stream and generating events
53
 */
54
public class Eml210SAXHandler extends DBSAXHandler implements
55
        AccessControlInterface
56
{
57

  
58
    private Vector allowRules = new Vector();
59

  
60
    private Vector denyRules = new Vector();
61

  
62
    private String documentId = null;
63

  
64
    private Vector subDocumentIdList = new Vector();
65

  
66
    private boolean processTopLeverAccess = false;
67

  
68
    private boolean processAdditionalAccess = false;
69

  
70
    private boolean processOtherAccess = false;
71

  
72
    private AccessSection accessObject = null;
73

  
74
    private AccessRule accessRule = null;
75

  
76
    private Vector accessObjectList = new Vector(); // store every access rule
77

  
78
    private Hashtable topLevelAccessControlMap = new Hashtable();
79

  
80
    private Hashtable additionalAccessControlMap = new Hashtable();// store
81

  
82
    //subtree access for single
83
    // additionalmetacat
84
    private Vector additionalAccessMapList = new Vector();// store maps for
85

  
86
    // every addionalmetadata
87
    private Vector describesId = new Vector(); // store the ids in
88

  
89
    //additionalmetadata/describes
90
    private Stack subTreeInfoStack = new Stack();
91

  
92
    private Vector subTreeList = new Vector();// store the final subtree
93

  
94
    private Hashtable unChangableSubTreeHash = new Hashtable();
95

  
96
    private Stack currentUnChangedableSubtreeNodeStack = new Stack();
97

  
98
    private boolean startCriticalSubTree = false;
99

  
100
    private boolean firstElementForCriticalSubTree = false;
101

  
102
    private String firstElementNameForCriticalSubTree;
103

  
104
    private boolean needCheckingAccessModule = false;
105

  
106
    private Vector unChangableAccessSubTreeVector = new Vector();
107

  
108
    private Stack currentUnchangableAccessModuleNodeStack = new Stack();
109

  
110
    private AccessSection topAccessSection;
111

  
112
    // we need an another stack to store the access node which we pull out just
113
    // from xml. If a reference happend, we can use the stack the compare nodes
114
    private Stack storedAccessNodeStack = new Stack();
115

  
116
    // vector stored the data file id which will be write into relation table
117
    private Vector onlineDataFileIdInRelationVector = new Vector();
118

  
119
    // vector stored the data file id which will be write top access rules to
120
   // access table
121
    private Vector onlineDataFileIdInTopAccessVector = new Vector();
122

  
123
    // Indicator of inline data
124
    private boolean handleInlineData = false;
125

  
126
    private Stack inlineDataNodeStack = null;
127

  
128
    private Hashtable inlineDataNameSpace = null;
129

  
130
    private FileWriter inlineDataFileWriter = null;
131

  
132
    private String inlineDataFileName = null;
133

  
134
    private int inLineDataIndex = 0;
135

  
136
    private Vector inlineFileIDList = new Vector();
137

  
138

  
139
    // Constant
140
    private static final String EML = "eml";
141

  
142
    private static final String DESCRIBES = "describes";
143

  
144
    private static final String ADDITIONALMETADATA = "additionalMetadata";
145

  
146
    private static final String ORDER = "order";
147

  
148
    private static final String ID = "id";
149

  
150
    private static final String REFERENCES = "references";
151

  
152
    public static final String INLINE = "inline";
153

  
154
    private static final String ONLINE = "online";
155

  
156
    private static final String URL = "url";
157

  
158
    private static final String PERMISSIONERROR = "User try to update a subtree"
159
            + " which it doesn't have write permission!";
160

  
161
    private static final String UPDATEACCESSERROR = "User try to update a "
162
            + "access module which it doesn't have \"ALL\" permission!";
163

  
164
    private static final String TOPLEVEL = "top";
165

  
166
    private static final String SUBTREELEVEL = "subtree";
167

  
168
    private static final String RELATION = "Provides info for";
169

  
170
    /**
171
     * Construct an instance of the handler class In this constructor, user can
172
     * specify the version need to upadate
173
     *
174
     * @param conn the JDBC connection to which information is written
175
     * @param action - "INSERT" or "UPDATE"
176
     * @param docid to be inserted or updated into JDBC connection
177
     * @param revision, the user specified the revision need to be update
178
     * @param user the user connected to MetaCat servlet and owns the document
179
     * @param groups the groups to which user belongs
180
     * @param pub flag for public "read" access on document
181
     * @param serverCode the serverid from xml_replication on which this
182
     *            document resides.
183
     *
184
     */
185
    public Eml210SAXHandler(DBConnection conn, String action, String docid,
186
            String revision, String user, String[] groups, String pub,
187
            int serverCode) throws SAXException
188
    {
189
        super(conn, action, docid, revision, user, groups, pub, serverCode);
190
        // Get the unchangable subtrees (user doesn't have write permission)
191
        try {
192
            PermissionController control = new PermissionController(docid
193
                    + MetaCatUtil.getOption("accNumSeparator") + revision);
194
            //unChangableSubTreeHash = getUnchangableSubTree(control, user,
195
            // groups);
196

  
197
            //If the action is update and user doesn't have "ALL" permission
198
            // we need to check if user update access subtree
199
            if (action.equals("UPDATE")
200
                    && !control.hasPermission(user, groups,
201
                            AccessControlInterface.ALLSTRING)) {
202
                needCheckingAccessModule = true;
203
                unChangableAccessSubTreeVector = getAccessSubTreeListFromDB();
204
            }
205
        } catch (Exception e) {
206
            throw new SAXException(e.getMessage());
207
        }
208
    }
209

  
210
    /* Pass a permission control and get the list of unchangable subtree */
211
    private Hashtable getUnchangableSubTree(PermissionController controller,
212
            String user, String[] groups) throws Exception
213
    {
214
        Hashtable list = null;
215
        Hashtable result = new Hashtable();
216
        // get unwritable sutree from controller
217
        list = controller.hasUnaccessableSubTree(user, groups,
218
                AccessControlInterface.WRITESTRING);
219
        if (list != null) {
220

  
221
            Enumeration en = list.elements();
222
            while (en.hasMoreElements()) {
223
                // Get a subtree without node record list
224
                SubTree treeWithoutStack = (SubTree) en.nextElement();
225
                String subTreeId = treeWithoutStack.getSubTreeId();
226
                MetaCatUtil.debugMessage(
227
                        "unchangable subtree id: " + subTreeId, 40);
228
                long startNodeId = treeWithoutStack.getStartNodeId();
229
                MetaCatUtil.debugMessage("unchangable subtree startnodeid: "
230
                        + startNodeId, 40);
231
                long endNodeId = treeWithoutStack.getEndNodeId();
232
                MetaCatUtil.debugMessage("unchangable subtree endnodeid: "
233
                        + endNodeId, 40);
234
                // Get a subtree has the nodelist
235
                SubTree tree = new SubTree(docid, subTreeId, startNodeId,
236
                        endNodeId);
237
                // add this tree to the result
238
                result.put(subTreeId, tree);
239

  
240
            }//while
241

  
242
        }//if
243

  
244
        return result;
245
    }
246

  
247
    /*
248
     * Get the subtree node info from xml_accesssubtree table
249
     */
250
    private Vector getAccessSubTreeListFromDB() throws Exception
251
    {
252
        Vector result = new Vector();
253
        PreparedStatement pstmt = null;
254
        ResultSet rs = null;
255
        String sql = "SELECT controllevel, subtreeid, startnodeid, endnodeid "
256
                + "FROM xml_accesssubtree WHERE docid like ? "
257
                + "ORDER BY startnodeid ASC";
258

  
259
        try {
260

  
261
            pstmt = connection.prepareStatement(sql);
262
            // Increase DBConnection usage count
263
            connection.increaseUsageCount(1);
264
            // Bind the values to the query
265
            pstmt.setString(1, docid);
266
            pstmt.execute();
267

  
268
            // Get result set
269
            rs = pstmt.getResultSet();
270
            while (rs.next()) {
271
                String level = rs.getString(1);
272
                String sectionId = rs.getString(2);
273
                long startNodeId = rs.getLong(3);
274
                long endNodeId = rs.getLong(4);
275
                // create a new access section
276
                AccessSection accessObj = new AccessSection();
277
                accessObj.setControlLevel(level);
278
                accessObj.setDocId(docid);
279
                accessObj.setSubTreeId(sectionId);
280
                accessObj.setStartNodeId(startNodeId);
281
                accessObj.setEndNodeId(endNodeId);
282
                Stack nodeStack = accessObj.getSubTreeNodeList();
283
                accessObj.setSubTreeNodeStack(nodeStack);
284
                // add this access obj into vector
285
                result.add(accessObj);
286
                // Get the top level access subtree control
287
                if (level != null && level.equals(TOPLEVEL)) {
288
                    topAccessSection = accessObj;
289
                }
290
            }
291
            pstmt.close();
292
        }//try
293
        catch (SQLException e) {
294
            throw new SAXException(
295
                    "EMLSAXHandler.getAccessSubTreeListFromDB(): "
296
                            + e.getMessage());
297
        }//catch
298
        finally {
299
            try {
300
                pstmt.close();
301
            } catch (SQLException ee) {
302
                throw new SAXException(
303
                        "EMLSAXHandler.getAccessSubTreeListFromDB(): "
304
                                + ee.getMessage());
305
            }
306
        }//finally
307
        return result;
308
    }
309

  
310
    /** SAX Handler that is called at the start of each XML element */
311
    public void startElement(String uri, String localName, String qName,
312
            Attributes atts) throws SAXException
313
    {
314
        // for element <eml:eml...> qname is "eml:eml", local name is "eml"
315
        // for element <acl....> both qname and local name is "eml"
316
        // uri is namesapce
317
        MetaCatUtil.debugMessage("Start ELEMENT(qName) " + qName, 50);
318
        MetaCatUtil.debugMessage("Start ELEMENT(localName) " + localName, 50);
319
        MetaCatUtil.debugMessage("Start ELEMENT(uri) " + uri, 50);
320

  
321
        DBSAXNode parentNode = null;
322
        DBSAXNode currentNode = null;
323

  
324
        if (!handleInlineData) {
325
            // Get a reference to the parent node for the id
326
            try {
327
                parentNode = (DBSAXNode) nodeStack.peek();
328
            } catch (EmptyStackException e) {
329
                parentNode = null;
330
            }
331

  
332
            //start handle inline data
333
            if (localName.equals(INLINE)) {
334
                handleInlineData = true;
335
                inLineDataIndex++;
336
                //intitialize namespace hash for in line data
337
                inlineDataNameSpace = new Hashtable();
338
                //initialize file writer
339
                String docidWithoutRev = MetaCatUtil.getDocIdFromString(docid);
340
                String seperator = MetaCatUtil.getOption("accNumSeparator");
341
                // the new file name will look like docid.rev.2
342
                inlineDataFileName = docidWithoutRev + seperator + revision
343
                        + seperator + inLineDataIndex;
344
                inlineDataFileWriter = createInlineDataFileWriter(inlineDataFileName);
345
                // put the inline file id into a vector. If upload failed,
346
                // metacat will
347
                // delete the inline data file
348
                inlineFileIDList.add(inlineDataFileName);
349

  
350
            }
351

  
352
            // If hit a text node, we need write this text for current's parent
353
            // node
354
            // This will happend if the element is mixted
355
            if (hitTextNode && parentNode != null) {
356
                //compare text node data for unchangesubtree
357
                if (startCriticalSubTree) {
358
                    compareTextNode(currentUnChangedableSubtreeNodeStack,
359
                            textBuffer, PERMISSIONERROR);
360
                }//if
361

  
362
                //compare top level access module
363
                if (processTopLeverAccess && needCheckingAccessModule) {
364
                    compareTextNode(currentUnchangableAccessModuleNodeStack,
365
                            textBuffer, UPDATEACCESSERROR);
366
                }
367

  
368
                if (needCheckingAccessModule
369
                        && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
370
                    // stored the pull out nodes into storedNode stack
371
                    NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "TEXT",
372
                            null, null, MetaCatUtil.normalize(textBuffer
373
                                    .toString()));
374
                    storedAccessNodeStack.push(nodeElement);
375

  
376
                }
377

  
378
                // write the textbuffer into db for parent node.
379
                endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
380
                        parentNode);
381
                // rest hitTextNode
382
                hitTextNode = false;
383
                // reset textbuffer
384
                textBuffer = null;
385
                textBuffer = new StringBuffer();
386

  
387
            }
388

  
389
            // Document representation that points to the root document node
390
            if (atFirstElement) {
391
                atFirstElement = false;
392
                // If no DOCTYPE declaration: docname = root element
393
                // doctype = root element name or name space
394
                if (docname == null) {
395
                    docname = localName;
396
                    // if uri isn't null doctype = uri(namespace)
397
                    // othewise root element
398
                    if (uri != null && !(uri.trim()).equals("")) {
399
                        doctype = uri;
400
                    } else {
401
                        doctype = docname;
402
                    }
403
                    MetaCatUtil.debugMessage("DOCNAME-a: " + docname, 30);
404
                    MetaCatUtil.debugMessage("DOCTYPE-a: " + doctype, 30);
405
                } else if (doctype == null) {
406
                    // because docname is not null and it is declared in dtd
407
                    // so could not be in schema, no namespace
408
                    doctype = docname;
409
                    MetaCatUtil.debugMessage("DOCTYPE-b: " + doctype, 30);
410
                }
411
                rootNode.writeNodename(docname);
412
                try {
413
                    // for validated XML Documents store a reference to XML DB
414
                    // Catalog
415
                    // Because this is select statement and it needn't to roll
416
                    // back if
417
                    // insert document action fialed.
418
                    // In order to decrease DBConnection usage count, we get a
419
                    // new
420
                    // dbconnection from pool
421
                    String catalogid = null;
422
                    DBConnection dbConn = null;
423
                    int serialNumber = -1;
424

  
425
                    try {
426
                        // Get dbconnection
427
                        dbConn = DBConnectionPool
428
                                .getDBConnection("DBSAXHandler.startElement");
429
                        serialNumber = dbConn.getCheckOutSerialNumber();
430

  
431
                        Statement stmt = dbConn.createStatement();
432
                        ResultSet rs = stmt
433
                                .executeQuery("SELECT catalog_id FROM xml_catalog "
434
                                        + "WHERE entry_type = 'Schema' "
435
                                        + "AND public_id = '" + doctype + "'");
436
                        boolean hasRow = rs.next();
437
                        if (hasRow) {
438
                            catalogid = rs.getString(1);
439
                        }
440
                        stmt.close();
441
                    }//try
442
                    finally {
443
                        // Return dbconnection
444
                        DBConnectionPool.returnDBConnection(dbConn,
445
                                serialNumber);
446
                    }//finally
447

  
448
                    //create documentImpl object by the constructor which can
449
                    // specify
450
                    //the revision
451
                    currentDocument = new DocumentImpl(connection, rootNode
452
                            .getNodeID(), docname, doctype, docid, revision,
453
                            action, user, this.pub, catalogid, this.serverCode);
454

  
455
                } catch (Exception ane) {
456
                    throw (new SAXException(
457
                            "Error in EMLSaxHandler.startElement " + action,
458
                            ane));
459
                }
460
            }
461

  
462
            // Create the current node representation
463
            currentNode = new DBSAXNode(connection, qName, localName,
464
                    parentNode, currentDocument.getRootNodeID(), docid,
465
                    currentDocument.getDoctype());
466
            // Use a local variable to store the element node id
467
            // If this element is a start point of subtree(section), it will be
468
            // stored
469
            // otherwise, it will be discated
470
            long startNodeId = currentNode.getNodeID();
471
            // Add all of the namespaces
472
            String prefix = null;
473
            String nsuri = null;
474
            Enumeration prefixes = namespaces.keys();
475
            while (prefixes.hasMoreElements()) {
476
                prefix = (String) prefixes.nextElement();
477
                nsuri = (String) namespaces.get(prefix);
478
                endNodeId = currentNode.setNamespace(prefix, nsuri, docid);
479
            }
480

  
481
            // Add all of the attributes
482
            for (int i = 0; i < atts.getLength(); i++) {
483
                String attributeName = atts.getQName(i);
484
                String attributeValue = atts.getValue(i);
485
                endNodeId = currentNode.setAttribute(attributeName,
486
                        attributeValue, docid);
487

  
488
                // To handle name space and schema location if the attribute
489
                // name is
490
                // xsi:schemaLocation. If the name space is in not in catalog
491
                // table
492
                // it will be regeistered.
493
                if (attributeName != null
494
                        && attributeName
495
                                .indexOf(MetaCatServlet.SCHEMALOCATIONKEYWORD) != -1) {
496
                    SchemaLocationResolver resolver = new SchemaLocationResolver(
497
                            attributeValue);
498
                    resolver.resolveNameSpace();
499

  
500
                } else if (attributeName != null && attributeName.equals(ID)) {
501

  
502
                    //check unchangedable subtree hash if contains this
503
                    // subtree id
504
                    if (unChangableSubTreeHash.containsKey(attributeValue)) {
505
                        // this subtree couldn't be changed by the user and
506
                        // move it from hash
507
                        SubTree currentUnChangedableSubtree = (SubTree) unChangableSubTreeHash
508
                                .remove(attributeValue);
509
                        currentUnChangedableSubtreeNodeStack = currentUnChangedableSubtree
510
                                .getSubTreeNodeStack();
511
                        startCriticalSubTree = true;
512
                        firstElementForCriticalSubTree = true;
513
                    }
514

  
515
                    // handle subtree info
516
                    SubTree subTress = new SubTree();
517
                    // set sub tree id
518
                    subTress.setSubTreeId(attributeValue);
519
                    // set sub tree sstart lement name
520
                    subTress.setStartElementName(currentNode.getTagName());
521
                    // set start node number
522
                    subTress.setStartNodeId(startNodeId);
523
                    // add to stack, but it didn't get end node id yet
524
                    subTreeInfoStack.push(subTress);
525

  
526
                }
527
            }//for
528

  
529
            // handle access stuff
530
            if (localName.equals(ACCESS)) {
531
                // if it is in addtionalmetacat
532
                if (parentNode.getTagName() == ADDITIONALMETADATA) {
533
                    processAdditionalAccess = true;
534

  
535
                } else {
536
                    //make sure the access is top level
537
                    // this mean current node's parent's parent should be "eml"
538
                    DBSAXNode tmpNode = (DBSAXNode) nodeStack.pop();// pop out
539
                                                                    // parent
540
                                                                    // node
541
                    //peek out grandParentNode
542
                    DBSAXNode grandParentNode = (DBSAXNode) nodeStack.peek();
543
                    // put parent node back
544
                    nodeStack.push(tmpNode);
545
                    String grandParentTag = grandParentNode.getTagName();
546
                    if (grandParentTag.equals(EML)) {
547
                        processTopLeverAccess = true;
548
                    } else {
549
                        // process other access embedded into resource level
550
                        // module
551
                        processOtherAccess = true;
552
                    }
553

  
554
                }
555
                // create access object
556
                accessObject = new AccessSection();
557
                // set permission order
558
                String permOrder = currentNode.getAttribute(ORDER);
559
                accessObject.setPermissionOrder(permOrder);
560
                // set access id
561
                String accessId = currentNode.getAttribute(ID);
562
                accessObject.setSubTreeId(accessId);
563
                accessObject.setStartNodeId(startNodeId);
564
                accessObject.setDocId(docid);
565

  
566
                // load top level node stack to
567
                // currentUnchangableAccessModuleNodeStack
568
                if (processTopLeverAccess && needCheckingAccessModule) {
569
                    // get the node stack for
570
                    currentUnchangableAccessModuleNodeStack = topAccessSection
571
                            .getSubTreeNodeStack();
572
                }
573

  
574
            }
575
            // Set up a access rule for allow
576
            else if (parentNode.getTagName() != null
577
                    && (parentNode.getTagName()).equals(ACCESS)
578
                    && localName.equals(ALLOW)) {
579

  
580
                accessRule = new AccessRule();
581

  
582
                //set permission type "allow"
583
                accessRule.setPermissionType(ALLOW);
584

  
585
            }
586
            // set up an access rule for den
587
            else if (parentNode.getTagName() != null
588
                    && (parentNode.getTagName()).equals(ACCESS)
589
                    && localName.equals(DENY)) {
590
                accessRule = new AccessRule();
591
                //set permission type "allow"
592
                accessRule.setPermissionType(DENY);
593
            }
594

  
595
            // Add the node to the stack, so that any text data can be
596
            // added as it is encountered
597
            nodeStack.push(currentNode);
598
            // Add the node to the vector used by thread for writing XML Index
599
            nodeIndex.addElement(currentNode);
600

  
601
            // handle critical subtree
602
            if (startCriticalSubTree && firstElementForCriticalSubTree) {
603
                //store the element name
604
                firstElementNameForCriticalSubTree = qName;
605
                firstElementForCriticalSubTree = false;
606
            }//for first element
607

  
608
            // handle critical subtree
609
            if (startCriticalSubTree) {
610
                compareElementNameSpaceAttributes(
611
                        currentUnChangedableSubtreeNodeStack, namespaces, atts,
612
                        localName, PERMISSIONERROR);
613

  
614
            }
615
            //compare top access level module
616
            if (processTopLeverAccess && needCheckingAccessModule) {
617
                compareElementNameSpaceAttributes(
618
                        currentUnchangableAccessModuleNodeStack, namespaces,
619
                        atts, localName, UPDATEACCESSERROR);
620

  
621
            }
622

  
623
            // store access module element and attributes into stored stack
624
            if (needCheckingAccessModule
625
                    && (processAdditionalAccess || processOtherAccess || processTopLeverAccess)) {
626
                // stored the pull out nodes into storedNode stack
627
                NodeRecord nodeElement = new NodeRecord(-2, -2, -2, "ELEMENT",
628
                        localName, prefix, MetaCatUtil.normalize(null));
629
                storedAccessNodeStack.push(nodeElement);
630
                for (int i = 0; i < atts.getLength(); i++) {
631
                    String attributeName = atts.getQName(i);
632
                    String attributeValue = atts.getValue(i);
633
                    NodeRecord nodeAttribute = new NodeRecord(-2, -2, -2,
634
                            "ATTRIBUTE", attributeName, null, MetaCatUtil
635
                                    .normalize(attributeValue));
636
                    storedAccessNodeStack.push(nodeAttribute);
637
                }
638

  
639
            }
640

  
641
            // reset name space
642
            namespaces = null;
643
            namespaces = new Hashtable();
644
        }//not inline data
645
        else {
646
            // we don't buffer the inline data in characters() method
647
            // so start character don't need to hand text node.
648

  
649
            // inline data may be the xml format.
650
            StringBuffer inlineElements = new StringBuffer();
651
            inlineElements.append("<").append(qName);
652
            // append attributes
653
            for (int i = 0; i < atts.getLength(); i++) {
654
                String attributeName = atts.getQName(i);
655
                String attributeValue = atts.getValue(i);
656
                inlineElements.append(" ");
657
                inlineElements.append(attributeName);
658
                inlineElements.append("=\"");
659
                inlineElements.append(attributeValue);
660
                inlineElements.append("\"");
661
            }
662
            // append namespace
663
            String prefix = null;
664
            String nsuri = null;
665
            Enumeration prefixes = inlineDataNameSpace.keys();
666
            while (prefixes.hasMoreElements()) {
667
                prefix = (String) prefixes.nextElement();
668
                nsuri = (String) namespaces.get(prefix);
669
                inlineElements.append(" ");
670
                inlineElements.append("xmlns:");
671
                inlineElements.append(prefix);
672
                inlineElements.append("=\"");
673
                inlineElements.append(nsuri);
674
                inlineElements.append("\"");
675
            }
676
            inlineElements.append(">");
677
            //reset inline data name space
678
            inlineDataNameSpace = null;
679
            inlineDataNameSpace = new Hashtable();
680
            //write inline data into file
681
            MetaCatUtil.debugMessage("the inline element data is: "
682
                    + inlineElements.toString(), 50);
683
            writeInlineDataIntoFile(inlineDataFileWriter, inlineElements);
684
        }//else
685

  
686
    }
687

  
688
    private void compareElementNameSpaceAttributes(Stack unchangableNodeStack,
689
            Hashtable nameSpaces, Attributes attributes, String localName,
690
            String error) throws SAXException
691
    {
692
        //Get element subtree node stack (element node)
693
        NodeRecord elementNode = null;
694
        try {
695
            elementNode = (NodeRecord) unchangableNodeStack.pop();
696
        } catch (EmptyStackException ee) {
697
            MetaCatUtil
698
                    .debugMessage("Node stack is empty for element data", 35);
699
            throw new SAXException(error);
700
        }
701
        MetaCatUtil.debugMessage("current node type from xml is ELEMENT", 40);
702
        MetaCatUtil.debugMessage("node type from stack: "
703
                + elementNode.getNodeType(), 40);
704
        MetaCatUtil.debugMessage("node name from xml document: " + localName,
705
                40);
706
        MetaCatUtil.debugMessage("node name from stack: "
707
                + elementNode.getNodeName(), 40);
708
        MetaCatUtil.debugMessage("node data from stack: "
709
                + elementNode.getNodeData(), 40);
710
        MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(), 40);
711
        // if this node is not element or local name not equal or name space
712
        // not
713
        // equals, throw an exception
714
        if (!elementNode.getNodeType().equals("ELEMENT")
715
                || !localName.equals(elementNode.getNodeName()))
716
        //  (uri != null && !uri.equals(elementNode.getNodePrefix())))
717
        {
718
            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
719
            MetaCatUtil.debugMessage("current node type from xml is ELEMENT",
720
                    40);
721
            MetaCatUtil.debugMessage("node type from stack: "
722
                    + elementNode.getNodeType(), 40);
723
            MetaCatUtil.debugMessage("node name from xml document: "
724
                    + localName, 40);
725
            MetaCatUtil.debugMessage("node name from stack: "
726
                    + elementNode.getNodeName(), 40);
727
            MetaCatUtil.debugMessage("node data from stack: "
728
                    + elementNode.getNodeData(), 40);
729
            MetaCatUtil.debugMessage("node id is: " + elementNode.getNodeId(),
730
                    40);
731
            throw new SAXException(error);
732
        }
733

  
734
        //compare namespace
735
        Enumeration nameEn = nameSpaces.keys();
736
        while (nameEn.hasMoreElements()) {
737
            //Get namespacke node stack (element node)
738
            NodeRecord nameNode = null;
739
            try {
740
                nameNode = (NodeRecord) unchangableNodeStack.pop();
741
            } catch (EmptyStackException ee) {
742
                MetaCatUtil.debugMessage(
743
                        "Node stack is empty for namespace data", 35);
744
                throw new SAXException(error);
745
            }
746

  
747
            String prefixName = (String) nameEn.nextElement();
748
            String nameSpaceUri = (String) nameSpaces.get(prefixName);
749
            if (!nameNode.getNodeType().equals("NAMESPACE")
750
                    || !prefixName.equals(nameNode.getNodeName())
751
                    || !nameSpaceUri.equals(nameNode.getNodeData())) {
752
                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
753
                MetaCatUtil.debugMessage(
754
                        "current node type from xml is NAMESPACE", 40);
755
                MetaCatUtil.debugMessage("node type from stack: "
756
                        + nameNode.getNodeType(), 40);
757
                MetaCatUtil.debugMessage("current node name from xml is: "
758
                        + prefixName, 40);
759
                MetaCatUtil.debugMessage("node name from stack: "
760
                        + nameNode.getNodeName(), 40);
761
                MetaCatUtil.debugMessage("current node data from xml is: "
762
                        + nameSpaceUri, 40);
763
                MetaCatUtil.debugMessage("node data from stack: "
764
                        + nameNode.getNodeData(), 40);
765
                MetaCatUtil.debugMessage("node id is: " + nameNode.getNodeId(),
766
                        40);
767
                throw new SAXException(error);
768
            }
769

  
770
        }//while
771

  
772
        //compare attributes
773
        for (int i = 0; i < attributes.getLength(); i++) {
774
            NodeRecord attriNode = null;
775
            try {
776
                attriNode = (NodeRecord) unchangableNodeStack.pop();
777

  
778
            } catch (EmptyStackException ee) {
779
                MetaCatUtil.debugMessage(
780
                        "Node stack is empty for attribute data", 35);
781
                throw new SAXException(error);
782
            }
783
            String attributeName = attributes.getQName(i);
784
            String attributeValue = attributes.getValue(i);
785
            MetaCatUtil.debugMessage(
786
                    "current node type from xml is ATTRIBUTE ", 40);
787
            MetaCatUtil.debugMessage("node type from stack: "
788
                    + attriNode.getNodeType(), 40);
789
            MetaCatUtil.debugMessage("current node name from xml is: "
790
                    + attributeName, 40);
791
            MetaCatUtil.debugMessage("node name from stack: "
792
                    + attriNode.getNodeName(), 40);
793
            MetaCatUtil.debugMessage("current node data from xml is: "
794
                    + attributeValue, 40);
795
            MetaCatUtil.debugMessage("node data from stack: "
796
                    + attriNode.getNodeData(), 40);
797
            MetaCatUtil.debugMessage("node id  is: " + attriNode.getNodeId(),
798
                    40);
799

  
800
            if (!attriNode.getNodeType().equals("ATTRIBUTE")
801
                    || !attributeName.equals(attriNode.getNodeName())
802
                    || !attributeValue.equals(attriNode.getNodeData())) {
803
                MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
804
                MetaCatUtil.debugMessage(
805
                        "current node type from xml is ATTRIBUTE ", 40);
806
                MetaCatUtil.debugMessage("node type from stack: "
807
                        + attriNode.getNodeType(), 40);
808
                MetaCatUtil.debugMessage("current node name from xml is: "
809
                        + attributeName, 40);
810
                MetaCatUtil.debugMessage("node name from stack: "
811
                        + attriNode.getNodeName(), 40);
812
                MetaCatUtil.debugMessage("current node data from xml is: "
813
                        + attributeValue, 40);
814
                MetaCatUtil.debugMessage("node data from stack: "
815
                        + attriNode.getNodeData(), 40);
816
                MetaCatUtil.debugMessage("node is: " + attriNode.getNodeId(),
817
                        40);
818
                throw new SAXException(error);
819
            }
820
        }//for
821

  
822
    }
823

  
824
    /* mehtod to compare current text node and node in db */
825
    private void compareTextNode(Stack nodeStack, StringBuffer text,
826
            String error) throws SAXException
827
    {
828
        NodeRecord node = null;
829
        //get node from current stack
830
        try {
831
            node = (NodeRecord) nodeStack.pop();
832
        } catch (EmptyStackException ee) {
833
            MetaCatUtil.debugMessage(
834
                    "Node stack is empty for text data in startElement", 35);
835
            throw new SAXException(error);
836
        }
837
        MetaCatUtil.debugMessage(
838
                "current node type from xml is TEXT in start element", 40);
839
        MetaCatUtil.debugMessage("node type from stack: " + node.getNodeType(),
840
                40);
841
        MetaCatUtil.debugMessage("current node data from xml is: "
842
                + text.toString(), 40);
843
        MetaCatUtil.debugMessage("node data from stack: " + node.getNodeData(),
844
                40);
845
        MetaCatUtil.debugMessage("node name from stack: " + node.getNodeName(),
846
                40);
847
        MetaCatUtil.debugMessage("node is: " + node.getNodeId(), 40);
848
        if (!node.getNodeType().equals("TEXT")
849
                || !(text.toString()).equals(node.getNodeData())) {
850
            MetaCatUtil.debugMessage("Inconsistence happend: ", 40);
851
            MetaCatUtil.debugMessage(
852
                    "current node type from xml is TEXT in start element", 40);
853
            MetaCatUtil.debugMessage("node type from stack: "
854
                    + node.getNodeType(), 40);
855
            MetaCatUtil.debugMessage("current node data from xml is: "
856
                    + text.toString(), 40);
857
            MetaCatUtil.debugMessage("node data from stack: "
858
                    + node.getNodeData(), 40);
859
            MetaCatUtil.debugMessage("node name from stack: "
860
                    + node.getNodeName(), 40);
861
            MetaCatUtil.debugMessage("node is: " + node.getNodeId(), 40);
862
            throw new SAXException(error);
863
        }//if
864
    }
865

  
866
    /** SAX Handler that is called for each XML text node */
867
    public void characters(char[] cbuf, int start, int len) throws SAXException
868
    {
869
        MetaCatUtil.debugMessage("CHARACTERS", 50);
870
        if (!handleInlineData) {
871
            // buffer all text nodes for same element. This is for text was
872
            // splited
873
            // into different nodes
874
            textBuffer.append(new String(cbuf, start, len));
875
            // set hittextnode true
876
            hitTextNode = true;
877
            // if text buffer .size is greater than max, write it to db.
878
            // so we can save memory
879
            if (textBuffer.length() > MAXDATACHARS) {
880
                MetaCatUtil
881
                        .debugMessage(
882
                                "Write text into DB in charaters"
883
                                        + " when text buffer size is greater than maxmum number",
884
                                50);
885
                DBSAXNode currentNode = (DBSAXNode) nodeStack.peek();
886
                endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
887
                        currentNode);
888
                textBuffer = null;
889
                textBuffer = new StringBuffer();
890
            }
891
        } else {
892
            // this is inline data and write file system directly
893
            // we don't need to buffered it.
894
            StringBuffer inlineText = new StringBuffer();
895
            inlineText.append(new String(cbuf, start, len));
896
            MetaCatUtil.debugMessage(
897
                    "The inline text data write into file system: "
898
                            + inlineText.toString(), 50);
899
            writeInlineDataIntoFile(inlineDataFileWriter, inlineText);
900
        }
901
    }
902

  
903
    /** SAX Handler that is called at the end of each XML element */
904
    public void endElement(String uri, String localName, String qName)
905
            throws SAXException
906
    {
907
        MetaCatUtil.debugMessage("End ELEMENT " + qName, 50);
908

  
909
        if (localName.equals(INLINE) && handleInlineData) {
910
            // Get the node from the stack
911
            DBSAXNode currentNode = (DBSAXNode) nodeStack.pop();
912
            String currentTag = currentNode.getTagName();
913
            MetaCatUtil.debugMessage("End of inline data", 35);
914
            // close file writer
915
            try {
916
                inlineDataFileWriter.close();
917
                handleInlineData = false;
918
            } catch (IOException ioe) {
919
                throw new SAXException(ioe.getMessage());
920
            }
921

  
922
            //check if user changed inine data or not if user doesn't have
923
            // write permission
924
            if (startCriticalSubTree) {
925
                NodeRecord node = null;
926
                String inlineData;
927
                try {
928
                    node = (NodeRecord) currentUnChangedableSubtreeNodeStack
929
                            .pop();
930
                    // get file name from db
931
                    String fileName = node.getNodeData();
932
                    MetaCatUtil.debugMessage("in handle inline data", 35);
933
                    MetaCatUtil.debugMessage(
934
                            "the inline data file name from node is: "
935
                                    + fileName, 40);
936
                    if (!compareInlineDataFiles(fileName, inlineDataFileName)) {
937
                        MetaCatUtil.debugMessage(
938
                                "inline data was changed by a user"
939
                                        + " who doesn't have permission", 30);
940
                        throw new SAXException(PERMISSIONERROR);
941
                    }
942
                } catch (EmptyStackException ee) {
943
                    MetaCatUtil.debugMessage(
944
                            "the stack is empty for text data", 32);
945
                    throw new SAXException(PERMISSIONERROR);
946
                } catch (McdbException eee) {
947
                    throw new SAXException(eee.getMessage());
948
                } finally {
949
                    // delete the inline data file already in file system
950
                    deleteInlineDataFile(inlineDataFileName);
951
                }
952

  
953
            }//if
954
            // write put inline data file name into text buffer (without path)
955
            textBuffer = new StringBuffer(inlineDataFileName);
956
            // write file name into db
957
            endNodeId = writeTextForDBSAXNode(endNodeId, textBuffer,
958
                    currentNode);
959
            // reset textbuff
960
            textBuffer = null;
961
            textBuffer = new StringBuffer();
962
            return;
963
        }
964

  
965
        if (!handleInlineData) {
966
            // Get the node from the stack
967
            DBSAXNode currentNode = (DBSAXNode) nodeStack.pop();
968
            String currentTag = currentNode.getTagName();
969

  
970
            // If before the end element, the parser hit text nodes and store
971
            // them
972
            // into the buffer, write the buffer to data base. The reason we
973
            // put
974
            // write database here is for xerces some time split text node
975
            if (hitTextNode) {
976
                // get access value
977
                String data = null;
978
                // add principal
979
                if (currentTag.equals(PRINCIPAL) && accessRule != null) {
980
                    data = (textBuffer.toString()).trim();
981
                    accessRule.addPrincipal(data);
982

  
983
                } else if (currentTag.equals(PERMISSION) && accessRule != null) {
984
                    data = (textBuffer.toString()).trim();
985
                    // we conbine different a permission into one value
986
                    int permission = accessRule.getPermission();
987
                    // add permision
988
                    if (data.toUpperCase().equals(READSTRING)) {
989
                        permission = permission | READ;
990
                    } else if (data.toUpperCase().equals(WRITESTRING)) {
991
                        permission = permission | WRITE;
992
                    } else if (data.toUpperCase().equals(CHMODSTRING)) {
993
                        permission = permission | CHMOD;
994
                    } else if (data.toUpperCase().equals(ALLSTRING)) {
995
                        permission = permission | ALL;
996
                    }
997
                    accessRule.setPermission(permission);
998
                }
999
                // put additionalmetadata/describes into vector
1000
                else if (currentTag.equals(DESCRIBES)) {
1001
                    data = (textBuffer.toString()).trim();
1002
                    describesId.add(data);
1003
                } else if (currentTag.equals(REFERENCES)
1004
                        && (processTopLeverAccess || processAdditionalAccess || processOtherAccess)) {
1005
                    // get reference
1006
                    data = (textBuffer.toString()).trim();
1007
                    // put reference id into accessSection
1008
                    accessObject.setReferences(data);
1009

  
1010
                } else if (currentTag.equals(URL)) {
1011
                    //handle online data, make sure its'parent is online
1012
                    DBSAXNode parentNode = (DBSAXNode) nodeStack.peek();
1013
                    if (parentNode != null && parentNode.getTagName() != null
1014
                            && parentNode.getTagName().equals(ONLINE)) {
1015
                        // if online data is in local metacat, add it to the
1016
                        // vector
1017
                        data = (textBuffer.toString()).trim();
1018
                        handleOnlineUrlDataFile(data);
1019
                        /*if (data != null
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff