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-10-30 16:41:37 -0800 (Wed, 30 Oct 2002) $'
10
 * '$Revision: 1321 $'
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
           for (int j = 0; j < principal.size(); j++ )
302
           {
303
             oneAccessRule = (String)principal.elementAt(j)+" ";
304
             oneAccessRule = oneAccessRule + leavingTagName + " ";
305
             oneAccessRule = oneAccessRule + permission + " ";
306
             oneAccessRule = oneAccessRule + permOrder;
307
             // inserinto accessRuleVector
308
             accessRuleVector.addElement(oneAccessRule);
309
           }
310
        } 
311
        catch (Exception e) 
312
        {
313
          throw new SAXException(e);
314
        }
315
      }
316

    
317
      // reset the allow/deny permission
318
      principal = new Vector();
319
      permission = 0;
320
      beginTime = null;
321
      endTime = null;
322
      ticketCount = 0;
323
    
324
    }
325

    
326
  }
327

    
328
  /** 
329
    * SAX Handler that receives notification of DOCTYPE. Sets the DTD.
330
    * @param name name of the DTD
331
    * @param publicId Public Identifier of the DTD
332
    * @param systemId System Identifier of the DTD
333
    */
334
  public void startDTD(String name, String publicId, String systemId) 
335
              throws SAXException {
336
    docname = name;
337
    doctype = publicId;
338
    systemid = systemId;
339
  }
340

    
341
  /** 
342
   * SAX Handler that receives notification of the start of entities.
343
   * @param name name of the entity
344
   */
345
  public void startEntity(String name) throws SAXException {
346
    if (name.equals("[dtd]")) {
347
      processingDTD = true;
348
    }
349
  }
350

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

    
361
  /**
362
   * Get the document name.
363
   */
364
  public String getDocname() {
365
    return docname;
366
  }
367

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

    
440
 
441

    
442
 
443
 
444
  /* Get the int value of READ, WRITE or ALL. */
445
  private static int intValue ( String permission )
446
  {
447
    if ( permission.equals("READ") ) {
448
      return READ;
449
    } else if ( permission.equals("WRITE") ) {
450
      return WRITE;
451
    } else if ( permission.equals("ALL") ) {
452
      return ALL;
453
    }
454
    
455
    return -1;
456
  }
457

    
458
  /* Get the text value of READ, WRITE or ALL. */
459
  private String txtValue ( int permission )
460
  {
461
    StringBuffer txtPerm = new StringBuffer("\"");
462
    if ( (permission & READ) != 0 ) {
463
      txtPerm.append("read");
464
    } 
465
    if ( (permission & WRITE) != 0 ) {
466
      if ( txtPerm.length() > 0 ) txtPerm.append(",");
467
      txtPerm.append("write");
468
    }
469
    if ( (permission & ALL) != 0 ) {
470
      if ( txtPerm.length() > 0 ) txtPerm.append(",");
471
      txtPerm.append("all");
472
    }
473

    
474
    return txtPerm.append("\"").toString();
475
  }
476

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