Project

General

Profile

« Previous | Next » 

Revision 819

Added by bojilova over 22 years ago

- when the Access file goes first before the Package file (eml-dataset-2.0)
relations are not available in xml_relation, thus updated the code
to check and run ACL also after the Package file is saved.
- cut out the rev# from subject and object in xml_relation as needed by ACL
- put missing pstmt.close in RelationHandler.

View differences:

src/edu/ucsb/nceas/metacat/DBSAXHandler.java
214 214

  
215 215
  }
216 216
  
217
  // The run method of xmlIndex thread. It writes XML Index for the document.
217
  /* The run method of xmlIndex thread. It writes XML Index for the document. */
218 218
  public void run () {
219 219
    DBSAXNode currNode = null;
220 220
    DBSAXNode prevNode = null;
......
238 238
    
239 239
      dbconn.commit();
240 240
         
241
      //if this is a package file then write the package info to 
242
      //the xml_relation table. RelationHandler checks to see
243
      //if it is a package file so you don't have to do it here.
241
      //if this is a package file
244 242
      if ( doctype.equals(util.getOption("packagedoctype")) )
245 243
      {
246
        //DocumentImpl xmldoc = new DocumentImpl(dbconn, docid);
244
        // write the package info to xml_relation table
247 245
        RelationHandler rth = new RelationHandler(docid, dbconn);
248
      } 
249
      else if ( doctype.equals(util.getOption("accessdoctype")) ) 
250
      {
251
        DocumentImpl xmldoc = new DocumentImpl(dbconn, docid);
252
        String xml = xmldoc.toString();
253
        try {
254
          AccessControlList aclobj = 
255
          new AccessControlList(dbconn, docid, new StringReader(xml),
256
                                user, groups, serverCode);
257
          dbconn.commit();
258
        } catch (SAXException e) {
259
          try {
260
            dbconn.rollback();
261
            dbconn.close();
262
          } catch (SQLException sqle) {}
263
          System.out.println("Error writing ACL in DBSaxHandler.run " + 
264
                             e.getMessage()); 
246
        // from the relations get the access file id for that package
247
        String aclid = rth.getAccessFileID(docid);
248
        // if there are access file, write ACL for that package
249
        if ( aclid != null ) {
250
          runAccessControlList(dbconn, aclid);
265 251
        }
266 252
      }
253
      // if it is an access file
254
      else if ( doctype.equals(util.getOption("accessdoctype")) )
255
      {
256
        // write ACL for the package
257
        runAccessControlList(dbconn, docid);
258
      }
267 259
      
268
      
269 260
      dbconn.close();
270 261

  
271 262
    } catch (Exception e) {
......
273 264
        dbconn.rollback();
274 265
        dbconn.close();
275 266
      } catch (SQLException sqle) {}
276
      System.out.println("Error writing XML Index in DBSaxHandler.run " + 
277
                         e.getMessage()); 
267
      System.out.println("Error in DBSAXHandler.run " + e.getMessage());
268
      e.printStackTrace();
278 269
    }      
279 270
  }
271
  
272
  // It runs in xmlIndex thread. It writes ACL for a package.
273
  private void runAccessControlList (Connection conn, String aclid)
274
                                                throws Exception
275
  {
276
    // read the access file from xml_nodes
277
    // parse the access file and store the access info into xml_access
278
    AccessControlList aclobj = 
279
    new AccessControlList(conn, aclid, //new StringReader(xml),
280
                          user, groups, serverCode);
281
    conn.commit();
282
  }
280 283

  
284

  
281 285
  /** SAX Handler that is called for each XML text node */
282 286
  public void characters(char[] cbuf, int start, int len) throws SAXException {
283 287
     MetaCatUtil.debugMessage("CHARACTERS");
src/edu/ucsb/nceas/metacat/RelationHandler.java
38 38
   * @param docid the ID of the XML document to index.
39 39
   */
40 40
  public RelationHandler(String docid, Connection conn)
41
              throws McdbException, SQLException, AccessionNumberException
41 42
  {
42 43
    this.conn = conn;
43 44
    this.docid = docid;
......
47 48
  /**
48 49
   * insert the relations specified in the triples into xml_relation table
49 50
   */ 
50
  public void putRelations() {
51
    
51
  private void putRelations() 
52
              throws McdbException, SQLException, AccessionNumberException
53
  {
54
    String packagetype = null;
55
    String subject = null;
56
    String subDoctype = null;
57
    String relationship = null;
58
    String object = null;
59
    String objDoctype = null;
60
    PreparedStatement pstmt = null; // to get the relations from xml_nodes
61
    PreparedStatement tstmt = null; // to insert each relation into xml_relation
52 62
    MetaCatUtil.debugMessage("Running relation handler!");
53 63

  
54
    // deletes all of the relations with a docid of @docid.
55
    //pseudo-code algorithm
56
    //for each new relation r in xml_nodes
57
    //  put r into xml_relation
58
    //  compare r to each relation already in xml_relation
59
    //  if r isrelatedto a row in xml_relation
60
    //    add a new row to xml_relation that represents this new relation
61
    try {
64
    /* 
65
     * PSEUDO-CODE ALGORITHM:
66
     * deletes all of the relations with a docid of @docid.
67
     * for each new relation r in xml_nodes
68
     *   put r into xml_relation
69
     */
62 70

  
63
      DocumentImpl xmldoc = new DocumentImpl(conn,docid,false);
64
      //DocumentImpl xmldoc = new DocumentImpl(conn);
65
      //xmldoc.getDocumentInfo(docid);
66
      String packagetype = xmldoc.getDoctype();
71
    //DocumentImpl xmldoc = new DocumentImpl(conn,docid,false);
72
    packagetype = (new DocumentImpl(conn,docid,false)).getDoctype();
67 73

  
68
      // first delete the relations for this package document if any
69
      deleteRelations(docid);
70
      // put the new relations
71
      PreparedStatement pstmt = conn.prepareStatement(
72
                                QuerySpecification.printPackageSQL(docid));
73
      pstmt.execute();
74
      
75
      //get the new relations out of xml_nodes
76
      ResultSet rs = pstmt.getResultSet();
77
      boolean hasmorerows = rs.next();
78
      while(hasmorerows) {
79
        String subject = rs.getString(1);
80
        String relationship = rs.getString(2);
81
        String object = rs.getString(3);
74
    // first delete the relations for this package document if any
75
    deleteRelations(docid);
82 76

  
83
        String subjectDoctype = null;
84
        String paramDocid = null;
85
        URL subjectMurl = null;
77
    // to put the new relations get them out of xml_nodes
78
    pstmt = conn.prepareStatement(QuerySpecification.printPackageSQL(docid));
79
    pstmt.execute();
80
    ResultSet rs = pstmt.getResultSet();
81
    boolean hasmorerows = rs.next();
82
    if (hasmorerows) {
83
      tstmt = conn.prepareStatement("INSERT INTO xml_relation (" +
84
                                    "docid,packagetype,subject,subdoctype," +
85
                                    "relationship, object, objdoctype) " + 
86
                                    "VALUES (?, ?, ?, ?, ?, ?, ?)");
87
    }
88
    while(hasmorerows) {
89
      subject = rs.getString(1);
90
      relationship = rs.getString(2);
91
      object = rs.getString(3);
86 92

  
87
        //get the current relations information
88
        String subDocid = null;
89
        String objDocid = null;
90
        String subDoctype = null;
91
        String objDoctype = null;
93
      // cut out the revision number for subject and object
94
      subject = (new DocumentIdentifier(subject)).getIdentifier();
95
      object = (new DocumentIdentifier(object)).getIdentifier();
96

  
97
      //subDoctype and objDoctype are N/A
98
      subDoctype = null;
99
      objDoctype = null;
100

  
101
      //put the new relation into xml_relation
102
      tstmt.setString(1, docid);
103
      tstmt.setString(2, packagetype);
104
      tstmt.setString(3, subject);
105
      tstmt.setString(4, subDoctype);
106
      tstmt.setString(5, relationship);
107
      tstmt.setString(6, object);
108
      tstmt.setString(7, objDoctype);
109
      tstmt.execute(); 
92 110
        
93
        try {
94
          URL subMurl = new URL(subject);
95
          if(subMurl.getQuery() != null) {
96
            Hashtable subMurlParams = util.parseQuery(subMurl.getQuery());
97
            subDocid = (String)subMurlParams.get("docid");
98
            if(subMurl.getProtocol().equals("metacat")) {
99
              DocumentImpl subDoc = new DocumentImpl(conn, subDocid);
100
              subDoctype = subDoc.getDoctype();
101
            }
102
          } else {
103
            subDocid = subject;
104
          }
105
        } catch(MalformedURLException murle) { 
106
          //assume this is just a docid not a url
107
          subDocid = subject;
108
        }
109
        
110
        try {
111
          URL objMurl = new URL(object); 
112
          if(objMurl.getQuery() != null) {
113
            Hashtable objMurlParams = util.parseQuery(objMurl.getQuery());
114
            objDocid = (String)objMurlParams.get("docid");
115
            if(objMurl.getProtocol().equals("metacat")) {
116
              DocumentImpl objDoc = new DocumentImpl(conn, objDocid);
117
              objDoctype = objDoc.getDoctype();
118
            }
119
          } else {
120
            objDocid = object;
121
          }
122
        } catch(MalformedURLException murle) {
123
          //assume this is just a docid
124
          objDocid = object;
125
        }
126
        
127
        
128
        //now that the comparisons are done, the new relation can be put
129
        //into xml_relation
130
        StringBuffer insertStmt = new StringBuffer();
131
        insertStmt.append("insert into xml_relation (docid, packagetype, ");
132
        insertStmt.append("subject, subdoctype, ");
133
        insertStmt.append("relationship, object, objdoctype) values ('");
134
        insertStmt.append(docid).append("', '");
135
        insertStmt.append(packagetype).append("', '");
136
        insertStmt.append(subject).append("', '");
137
        insertStmt.append(subDoctype).append("', '");
138
        insertStmt.append(relationship).append("', '");
139
        insertStmt.append(object).append("', '");
140
        insertStmt.append(objDoctype).append("')");
141
        
142
        pstmt = conn.prepareStatement(insertStmt.toString());
143
        pstmt.execute(); 
144
        
145
        hasmorerows = rs.next();
146
      }
111
      hasmorerows = rs.next();
112
    }
147 113
      
148
      pstmt.close();
149
      conn.commit();
150

  
151
    } catch(Exception e) { 
152
      MetaCatUtil.debugMessage("Error in RelationHandler.run(): " + 
153
                               e.getMessage());
154
      System.out.println("Error in RelationHandler.run(): " + 
155
                               e.getMessage());
156
      try { 
157
        conn.rollback();
158
      } catch (SQLException sqle) {
159
        System.out.println("Error in RelationHandler.run(): " + 
160
                           sqle.getMessage());
161
      }
114
    if ( tstmt != null ) {
115
      tstmt.close();
162 116
    }
117
    pstmt.close();
118
    conn.commit();
163 119
  }
164 120
  
165 121
  /**
166 122
   * Deletes all of the relations with a docid of 'docid'.
167
   * @param docid the docid to delete.
123
   * @param docid the docid of the package which relations to delete.
168 124
   */
169 125
  public void deleteRelations(String docid) throws SQLException
170 126
  {
171 127
    try {
172
      PreparedStatement pstmt = conn.prepareStatement("delete from " +
173
                             "xml_relation where docid like '" + docid + "'");
128
      PreparedStatement pstmt = conn.prepareStatement(
129
                                "DELETE FROM xml_relation " +
130
                                "WHERE docid = '" + docid + "'");
174 131
      pstmt.execute();
175 132
      pstmt.close();
176 133
    } catch(SQLException e) {
......
181 138
      throw e;
182 139
    }
183 140
  }
141

  
142
  /**
143
   * Get the access file id for a package
144
   * @param docid the document identifier of the package
145
   * @return the document identifier of the access file for that package
146
   */
147
  public String getAccessFileID(String docid) throws SQLException
148
  {
149
    String aclid = null;
150
    PreparedStatement pstmt = 
151
      conn.prepareStatement("SELECT docid FROM xml_documents " +
152
                            "WHERE docid in " +
153
                            "(SELECT subject FROM xml_relation " +
154
                            "WHERE docid = ?) " +
155
                            "AND doctype = ?");
156
    pstmt.setString(1, docid);
157
    pstmt.setString(2, MetaCatUtil.getOption("accessdoctype"));
158
    pstmt.execute();
159
    ResultSet rs = pstmt.getResultSet();
160
    boolean hasRow = rs.next();
161
    if (hasRow) {
162
      aclid = rs.getString(1);
163
    }
164
    pstmt.close();
165
    
166
    return aclid;
167
  }
168

  
184 169
}
src/edu/ucsb/nceas/metacat/AccessControlList.java
47 47
import org.xml.sax.helpers.XMLReaderFactory;
48 48
import org.xml.sax.helpers.DefaultHandler;
49 49

  
50
//import edu.ucsb.nceas.dbadapter.AbstractDatabase;
51

  
52 50
/** 
53 51
 * A Class that loads eml-access.xml file containing ACL for a metadata
54 52
 * document into relational DB. It extends DefaultHandler class to handle
......
116 114
   * @param serverCode the serverid from xml_replication on which this document
117 115
   *        resides.
118 116
   */
119
  public AccessControlList(Connection conn, String aclid, Reader acl,
117
  public AccessControlList(Connection conn, String aclid, //Reader acl,
120 118
                           String user, String[] groups, int serverCode)
121
                  throws SAXException, IOException, ClassNotFoundException,
122
                         Exception
119
                  throws SAXException, IOException, McdbException
123 120
  {
124 121
    String parserName = MetaCatUtil.getOption("saxparser");
125 122
    this.server = MetaCatUtil.getOption("server");
......
133 130
    this.user = user;
134 131
    this.groups = groups;
135 132
    this.aclid = aclid;
136
    DocumentImpl aclinfo = new DocumentImpl(conn,aclid,false);
137
    this.rev = aclinfo.getRev();
138 133
    this.resourceURL = new Vector();
139 134
    this.resourceID = new Vector();
140 135
    this.principal = new Vector();
......
143 138
  //  this.publicAcc = null;
144 139
    this.serverCode = serverCode;
145 140
    
146
    // Initialize the parser and read the queryspec
141
    // read the access file from db connection
142
    DocumentImpl acldoc = new DocumentImpl(conn, aclid);
143
    String acl = acldoc.toString();
144
    this.rev = acldoc.getRev();
145

  
146
    // Initialize the parse
147 147
    XMLReader parser = initializeParser();
148
    parser.parse(new InputSource(acl));
149

  
148
    // parse the access file and write the info to xml_access
149
    parser.parse(new InputSource(new StringReader(acl)));
150
    
150 151
  }
151 152

  
152
  /**
153
   * Construct an instance of the AccessControlList class.
154
   * It parses eml-access file and loads acl data into db connection.
155
   * It is used from command line execution.
156
   *
157
   * @param conn the JDBC connection where acl data are loaded
158
   * @param docid the Accession# of the document with the acl data
159
   * @param aclfilename the name of acl file containing acl data
160
   * @param user the user connected to MetaCat servlet and owns the document
161
   * @param groups the groups to which user belongs
162
   */
163
  public AccessControlList( Connection conn, String aclid, String aclfilename,
164
                           String user, String[] groups )
165
                  throws SAXException, IOException, ClassNotFoundException,
166
                         Exception
167
  {
168
    this(conn, aclid, new FileReader(new File(aclfilename).toString()), 
169
         user, groups, 1);
170
  }
153
// NOT USED
154
//  /**
155
//   * Construct an instance of the AccessControlList class.
156
//   * It parses eml-access file and loads acl data into db connection.
157
//   * It is used from command line execution.
158
//   *
159
//   * @param conn the JDBC connection where acl data are loaded
160
//   * @param docid the Accession# of the document with the acl data
161
//   * @param aclfilename the name of acl file containing acl data
162
//   * @param user the user connected to MetaCat servlet and owns the document
163
//   * @param groups the groups to which user belongs
164
//   */
165
//  public AccessControlList( Connection conn, String aclid, String aclfilename,
166
//                           String user, String[] groups )
167
//                  throws SAXException, IOException, McdbException
168
//  {
169
//    this(conn, aclid, new FileReader(new File(aclfilename).toString()), 
170
//         user, groups, 1);
171
//  }
171 172
  
172 173
  /* Set up the SAX parser for reading the XML serialized ACL */
173 174
  private XMLReader initializeParser() throws SAXException 
......
203 204
    //delete all previously submitted permissions @ relations
204 205
    //this happens only on UPDATE of the access file
205 206
    try {
206
      this.aclObjects = getACLObjects(aclid + sep + rev);
207
      this.aclObjects = getACLObjects(aclid);
207 208

  
209
      //delete all permissions for resources related to @aclid if any
208 210
      if ( aclid != null ) {
209
        //delete all permissions for resources related to @aclid if any
210 211
        deletePermissionsForRelatedResources(aclid);
211
      //  //then delete all relations with docid of @aclid if any
212
      //  deleteRelations(aclid);
213 212
      }
214 213
    } catch (SQLException sqle) {
215 214
      throw new SAXException(sqle);

Also available in: Unified diff