Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *    Authors: Jivka Bojilova
6
 *    Release: @release@
7
 *
8
 *   '$Author: tao $'
9
 *     '$Date: 2002-11-01 18:11:49 -0800 (Fri, 01 Nov 2002) $'
10
 * '$Revision: 1323 $'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26

    
27
package edu.ucsb.nceas.metacat;
28

    
29
import java.io.*;
30
import java.sql.*;
31
import java.util.Stack;
32
import java.util.Vector;
33
import java.util.Hashtable;
34
import java.net.URL;
35
import java.net.MalformedURLException;
36

    
37
import org.xml.sax.Attributes;
38
import org.xml.sax.InputSource;
39
import org.xml.sax.ContentHandler;
40
import org.xml.sax.EntityResolver;
41
import org.xml.sax.ErrorHandler;
42
import org.xml.sax.SAXException;
43
import org.xml.sax.SAXParseException;
44
import org.xml.sax.XMLReader;
45
import org.xml.sax.helpers.XMLReaderFactory;
46
import org.xml.sax.helpers.DefaultHandler;
47

    
48
/** 
49
 * A Class that read an eml-access.xml file containing ACL for a metadata
50
 * document and parse it into access rules
51
 */
52
public class AccessRulesFromDocument extends DefaultHandler {
53

    
54
  private static final int CHMOD = 1;
55
  private static final int WRITE = 2;
56
  private static final int READ = 4;
57
  private static final int ALL = 7;
58
  private static final String ALLOWFIRST="allowFirst";
59
  private static final String DENYFIRST="denyFirst";
60
  private static final String ALLOW="allow";
61
  private static final String DENY="deny";
62
  private static final String PUBLIC="public";
63
  private static String sysdate = MetaCatUtil.dbAdapter.getDateTimeFunction();
64
  private static String isnull = MetaCatUtil.dbAdapter.getIsNULLFunction();
65
  
66
  private String parserName;
67
  private Stack elementStack;
68
  private String server;
69
  private String sep;
70
 
71
  private boolean	processingDTD;
72
  private String  aclid;
73
  private int     rev;
74
  private String 	docname;
75
  private String 	doctype;
76
  private String 	systemid;
77

    
78
  private String docurl;
79
  private Vector resourceURL;
80
  private Vector resourceID;
81
  private Vector principal;
82
  private int    permission;
83
  private String permType;
84
  private String permOrder;
85
//  private String publicAcc;
86
  private String beginTime;
87
  private String endTime;
88
  private int    ticketCount;
89
  private int    serverCode = 1;
90

    
91
  private Vector aclObjects = new Vector();
92
  private boolean instarttag = true;
93
  private String tagName = "";
94
  private Vector accessRuleVector = new Vector();
95

    
96
  /**
97
   * Construct an instance of the AccessControlList class.
98
   * It parse acl file and loads acl data into db connection.
99
   *
100
   * @param aclid the Accession# of the document with the acl data
101
   * @param serverCode the serverid from xml_replication on which this document
102
   *        resides.
103
   */
104
  public AccessRulesFromDocument(String aclid)
105
                  throws SAXException, IOException, McdbException, SQLException
106
  {
107
    String parserName = MetaCatUtil.getOption("saxparser");
108
    this.server = MetaCatUtil.getOption("server");
109
    this.sep = MetaCatUtil.getOption("accNumSeparator");
110

    
111
 
112
    this.parserName = parserName;
113
    this.processingDTD = false;
114
    this.elementStack = new Stack();
115
    
116
    
117
    this.aclid = aclid;
118
    this.resourceURL = new Vector();
119
    this.resourceID = new Vector();
120
    this.principal = new Vector();
121
    this.permission = 0;
122
    this.ticketCount = 0;
123
 
124
    
125
    // read the access file from db connection
126
    DocumentImpl acldoc = new DocumentImpl(aclid);
127
    String acl = acldoc.toString();
128
    this.rev = acldoc.getRev();
129

    
130
    // Initialize the parse
131
    XMLReader parser = initializeParser();
132
    // parse the access file and write the info to xml_access
133
    parser.parse(new InputSource(new StringReader(acl)));
134
    
135
  }
136

    
137

    
138
  
139
  /* Set up the SAX parser for reading the XML serialized ACL */
140
  private XMLReader initializeParser() throws SAXException, SQLException
141
  {
142
    XMLReader parser = null;
143

    
144
    // Get an instance of the parser
145
    parser = XMLReaderFactory.createXMLReader(parserName);
146

    
147
    // Turn off validation
148
    parser.setFeature("http://xml.org/sax/features/validation", true);
149
      
150
    // Set Handlers in the parser
151
    // Set the ContentHandler to this instance
152
    parser.setContentHandler((ContentHandler)this);
153

    
154
    // make a DBEntityResolver instance
155
    // Set the EntityReslover to DBEntityResolver instance
156
    DBConnection conn = null;
157
    int serialNumber = -1;
158
    try
159
    {
160
      //get connection from DBConnectionPool
161
      conn=DBConnectionPool.getDBConnection("AccessControlList.getACLObject");
162
      serialNumber=conn.getCheckOutSerialNumber();
163
      EntityResolver eresolver = new DBEntityResolver(conn, this, null);
164
      parser.setEntityResolver((EntityResolver)eresolver);
165
    }
166
    finally
167
    {
168
      //retrun DBConnection
169
      DBConnectionPool.returnDBConnection(conn,serialNumber);
170
    }
171
    // Set the ErrorHandler to this instance
172
    parser.setErrorHandler((ErrorHandler)this);
173

    
174
    return parser; 
175
  }
176
  
177
  /**
178
   * Callback method used by the SAX Parser when beginning of the document
179
   */
180
  public void startDocument() throws SAXException 
181
  {
182
    //delete all previously submitted permissions @ relations
183
    //this happens only on UPDATE of the access file
184
    try {
185
      this.aclObjects = createACLObjects(aclid);
186

    
187
      //delete all permissions for resources related to @aclid if any
188
      /*if ( aclid != null ) {
189
        deletePermissionsForRelatedResources(aclid);
190
      }*/
191
    } catch (SQLException sqle) {
192
      throw new SAXException(sqle);
193
    }
194
  }
195
  
196
  /**
197
   * Callback method used by the SAX Parser when the start tag of an 
198
   * element is detected. Used in this context to parse and store
199
   * the acl information in class variables.
200
   */
201
  public void startElement (String uri, String localName, 
202
                            String qName, Attributes atts) 
203
         throws SAXException 
204
  {
205
    instarttag = true;
206
    if(localName.equals("allow"))
207
    {
208
      tagName = "allow";
209
    }
210
    else if(localName.equals("deny"))
211
    {
212
      tagName = "deny";
213
    }
214
    BasicNode currentNode = new BasicNode(localName);
215
    if (atts != null) {
216
      int len = atts.getLength();
217
      for (int i = 0; i < len; i++) {
218
        currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i));
219
      }
220
    }
221
    if ( currentNode.getTagName().equals("acl") ) {
222
      permOrder = currentNode.getAttribute("order");
223
   
224
    }
225
    elementStack.push(currentNode); 
226
  }
227

    
228
  /**
229
   * Callback method used by the SAX Parser when the text sequences of an 
230
   * xml stream are detected. Used in this context to parse and store
231
   * the acl information in class variables.
232
   */ 
233
  public void characters(char ch[], int start, int length)
234
         throws SAXException 
235
  {
236
    if(!instarttag)
237
    {
238
      return;
239
    }
240
    String inputString = new String(ch, start, length);
241
    inputString = inputString.trim(); 
242
    //System.out.println("==============inputString: " + inputString);
243
    BasicNode currentNode = (BasicNode)elementStack.peek(); 
244
    String currentTag = currentNode.getTagName();
245

    
246
      if (currentTag.equals("principal")) {
247

    
248
        principal.addElement(inputString);
249

    
250
      } else if (currentTag.equals("permission")) {
251

    
252
        if ( inputString.trim().toUpperCase().equals("READ") ) {
253
          permission = permission | READ;
254
        } else if ( inputString.trim().toUpperCase().equals("WRITE") ) {
255
          permission = permission | WRITE;
256
        } else if ( inputString.trim().toUpperCase().equals("CHANGEPERMISSION")) 
257
        {
258
          permission = permission | CHMOD;
259
        } else if ( inputString.trim().toUpperCase().equals("ALL") ) {
260
          permission = permission | ALL;
261
        }/*else{
262
          throw new SAXException("Unknown permission type: " + inputString);
263
        }*/
264

    
265
      } else if ( currentTag.equals("startDate") && beginTime == null ) {
266
        beginTime = inputString.trim();
267

    
268
      } else if ( currentTag.equals("stopDate") && endTime == null) {
269
        endTime = inputString.trim();
270

    
271
      } else if (currentTag.equals("ticketCount") && ticketCount == 0 ) {
272
        try {
273
          ticketCount = (new Integer(inputString.trim())).intValue();
274
        } catch (NumberFormatException nfe) {
275
          throw new SAXException("Wrong integer format for:" + inputString);
276
        }
277
      }
278
  }
279

    
280
  /**
281
   * Callback method used by the SAX Parser when the end tag of an 
282
   * element is detected. Used in this context to parse and store
283
   * the acl information in class variables.
284
   */
285
  public void endElement (String uri, String localName, String qName)
286
         throws SAXException 
287
  {
288
    String oneAccessRule = null; 
289
    instarttag = false;
290
    BasicNode leaving = (BasicNode)elementStack.pop();
291
    String leavingTagName = leaving.getTagName();
292

    
293
    if ( leavingTagName.equals("allow") ||
294
         leavingTagName.equals("deny")    ) {
295
      
296
      if ( permission > 0 ) {
297

    
298
        // create a rule string an put it into rule vector.
299
        try 
300
        {
301
           if (permOrder != null)
302
           {
303
             permOrder = permOrder.trim();
304
           }
305
           for (int j = 0; j < principal.size(); j++ )
306
           {
307
             String onePrincipal = (String)principal.elementAt(j);
308
             if (onePrincipal != null)
309
             {
310
               onePrincipal= onePrincipal.trim();
311
             }
312
             oneAccessRule = onePrincipal + CleanupAccessTable.DELIMITER;
313
             oneAccessRule = oneAccessRule + leavingTagName + CleanupAccessTable.DELIMITER;
314
             oneAccessRule = oneAccessRule + permission + CleanupAccessTable.DELIMITER;
315
             oneAccessRule = oneAccessRule + permOrder;
316
             // inserinto accessRuleVector
317
             accessRuleVector.addElement(oneAccessRule);
318
           }
319
        } 
320
        catch (Exception e) 
321
        {
322
          throw new SAXException(e);
323
        }
324
      }
325

    
326
      // reset the allow/deny permission
327
      principal = new Vector();
328
      permission = 0;
329
      beginTime = null;
330
      endTime = null;
331
      ticketCount = 0;
332
    
333
    }
334

    
335
  }
336

    
337
  /** 
338
    * SAX Handler that receives notification of DOCTYPE. Sets the DTD.
339
    * @param name name of the DTD
340
    * @param publicId Public Identifier of the DTD
341
    * @param systemId System Identifier of the DTD
342
    */
343
  public void startDTD(String name, String publicId, String systemId) 
344
              throws SAXException {
345
    docname = name;
346
    doctype = publicId;
347
    systemid = systemId;
348
  }
349

    
350
  /** 
351
   * SAX Handler that receives notification of the start of entities.
352
   * @param name name of the entity
353
   */
354
  public void startEntity(String name) throws SAXException {
355
    if (name.equals("[dtd]")) {
356
      processingDTD = true;
357
    }
358
  }
359

    
360
  /** 
361
   * SAX Handler that receives notification of the end of entities.
362
   * @param name name of the entity
363
   */
364
  public void endEntity(String name) throws SAXException {
365
    if (name.equals("[dtd]")) {
366
      processingDTD = false;
367
    }
368
  }
369

    
370
  /**
371
   * Get the document name.
372
   */
373
  public String getDocname() {
374
    return docname;
375
  }
376

    
377
  /**
378
   * Get the document processing state.
379
   */
380
  public boolean processingDTD() {
381
    return processingDTD;
382
  }
383
  
384
  /**
385
   * Method to get accessRuleVector
386
   */
387
  public Vector getAccessRuleVector()
388
  {
389
    return accessRuleVector;
390
  }
391
  
392
  /**
393
   * Method to get ACLObjects
394
   */
395
  public Vector getACLObjects()
396
  {
397
    return aclObjects;
398
  }
399
  
400
  /* Get all objects associated with @aclid from db.*/
401
  private Vector createACLObjects(String aclid) 
402
          throws SQLException 
403
  {
404
    Vector aclObjects = new Vector();
405
    DBConnection conn = null;
406
    int serialNumber = -1;
407
    PreparedStatement pstmt = null;
408
    try
409
    {
410
      //get connection from DBConnectionPool
411
      conn=DBConnectionPool.getDBConnection("AccessControlList.getACLObject");
412
      serialNumber=conn.getCheckOutSerialNumber();
413
      
414
      // delete all acl records for resources related to @aclid if any
415
      pstmt = conn.prepareStatement(
416
                             "SELECT object FROM xml_relation " +
417
                             "WHERE subject = ? ");
418
      pstmt.setString(1,aclid);
419
      pstmt.execute();
420
      ResultSet rs = pstmt.getResultSet();
421
      boolean hasRows = rs.next();
422
      while (hasRows) {
423
        aclObjects.addElement(rs.getString(1));
424
        hasRows = rs.next();
425
      }//while
426
      // Add access file itself
427
      //aclObjects.addElement(aclid);
428
    }
429
    catch (SQLException e)
430
    {
431
      throw e;
432
    }
433
    finally
434
    {
435
      try
436
      {
437
        pstmt.close();
438
      }
439
      finally
440
      {
441
        //retrun DBConnection
442
        DBConnectionPool.returnDBConnection(conn,serialNumber);
443
      }
444
    }
445
    
446
    return aclObjects;
447
  }
448

    
449
 
450

    
451
 
452
 
453
  /* Get the int value of READ, WRITE or ALL. */
454
  private static int intValue ( String permission )
455
  {
456
    if ( permission.equals("READ") ) {
457
      return READ;
458
    } else if ( permission.equals("WRITE") ) {
459
      return WRITE;
460
    } else if ( permission.equals("ALL") ) {
461
      return ALL;
462
    }
463
    
464
    return -1;
465
  }
466

    
467
  /* Get the text value of READ, WRITE or ALL. */
468
  private String txtValue ( int permission )
469
  {
470
    StringBuffer txtPerm = new StringBuffer("\"");
471
    if ( (permission & READ) != 0 ) {
472
      txtPerm.append("read");
473
    } 
474
    if ( (permission & WRITE) != 0 ) {
475
      if ( txtPerm.length() > 0 ) txtPerm.append(",");
476
      txtPerm.append("write");
477
    }
478
    if ( (permission & ALL) != 0 ) {
479
      if ( txtPerm.length() > 0 ) txtPerm.append(",");
480
      txtPerm.append("all");
481
    }
482

    
483
    return txtPerm.append("\"").toString();
484
  }
485

    
486
  public static void main(String[] agus)
487
  {
488
    if(agus.length == 0)
489
    {
490
      System.out.println("you should specify a docid!");
491
      return;
492
    }
493
    String docID = agus[0];
494
    try
495
    {
496
      DBConnectionPool pool = DBConnectionPool.getInstance();
497
      AccessRulesFromDocument xmlDocument = new AccessRulesFromDocument(docID);
498
      Vector rules = xmlDocument.getAccessRuleVector();
499
      Vector docid = xmlDocument.getACLObjects();
500
      for (int i = 0; i<rules.size(); i++)
501
      {
502
        System.out.println("rule: "+(String)rules.elementAt(i));
503
      }
504
      for (int i = 0; i<docid.size(); i++)
505
      {
506
        System.out.println("docid: "+(String)docid.elementAt(i));
507
      }
508
    }
509
    catch(Exception e)
510
    {
511
      System.out.println("exception is: "+e.getMessage());
512
    }
513
  }
514
  
515
}
(3-3/48)