Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that loads eml-access.xml file containing ACL 
4
 *             for a metadata document into relational DB
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jivka Bojilova
8
 *    Release: @release@
9
 *
10
 *   '$Author: bojilova $'
11
 *     '$Date: 2000-11-21 10:04:37 -0800 (Tue, 21 Nov 2000) $'
12
 * '$Revision: 555 $'
13
 */
14

    
15
package edu.ucsb.nceas.metacat;
16

    
17
import java.io.*;
18
import java.sql.*;
19
import java.util.Stack;
20
import java.util.Vector;
21

    
22
import org.xml.sax.Attributes;
23
import org.xml.sax.InputSource;
24
import org.xml.sax.SAXException;
25
import org.xml.sax.SAXParseException;
26
import org.xml.sax.XMLReader;
27
import org.xml.sax.helpers.XMLReaderFactory;
28
import org.xml.sax.helpers.DefaultHandler;
29

    
30
/** 
31
 * A Class that loads eml-access.xml file containing ACL for a metadata
32
 * document into relational DB. It extends DefaultHandler class to handle
33
 * SAX parsing events when processing the XML stream.
34
 */
35
public class AccessControlList extends DefaultHandler {
36

    
37
  static final int ALL = 1;
38
  static final int WRITE = 2;
39
  static final int READ = 4;
40

    
41
  private Connection  conn;
42
  private String docid;
43
  private String parserName;
44
  private Stack elementStack;
45

    
46
  private Vector allow  = new Vector();
47
  private Vector begin1 = new Vector();
48
  private Vector end1   = new Vector();
49
  private Vector count1 = new Vector();
50

    
51
  private Vector denyv  = new Vector();
52
  private Vector begin2 = new Vector();
53
  private Vector end2   = new Vector();
54
  private Vector count2 = new Vector();
55
  
56
  private String principal_name = "";
57
  private String principal_type;
58
  private int permission = 0;
59
  private String begin_time;
60
  private String end_time;
61
  private int count;
62
  private int deny;
63
  
64
  /**
65
   * Construct an instance of the AccessControlList class.
66
   * It parse acl file and loads acl data into db connection.
67
   *
68
   * @param conn the JDBC connection where acl data are loaded
69
   * @param docid the Accession# of the document with the acl data
70
   * @param acl the acl file containing acl data for the document
71
   */
72
  public AccessControlList ( Connection conn, String docid, Reader acl )
73
                  throws SAXException, IOException, ClassNotFoundException 
74
  {
75
    // Get an instance of the parser
76
    MetaCatUtil util = new MetaCatUtil();
77
    String parserName = util.getOption("saxparser");
78

    
79
    this.conn = conn;
80
    this.docid = docid;
81
    this.parserName = parserName;
82
    elementStack = new Stack();
83

    
84
    // Initialize the parser and read the queryspec
85
    XMLReader parser = initializeParser();
86
    parser.parse(new InputSource(acl));
87

    
88
  }
89

    
90
  public AccessControlList( Connection conn, String docid, String aclfilename )
91
                  throws SAXException, IOException, ClassNotFoundException 
92
  {
93
    this(conn,docid,new FileReader(new File(aclfilename).toString()));
94
  }
95

    
96
  /**
97
   * Set up the SAX parser for reading the XML serialized ACL
98
   */
99
  private XMLReader initializeParser() throws SAXException 
100
  {
101
    XMLReader parser = null;
102

    
103
    // Get an instance of the parser
104
    parser = XMLReaderFactory.createXMLReader(parserName);
105

    
106
    // Set the ContentHandler to this instance
107
    parser.setContentHandler(this);
108

    
109
    // Set the ErrorHandler to this instance
110
    parser.setErrorHandler(this);
111

    
112
    return parser;
113
  }
114
  
115
  /**
116
   * callback method used by the SAX Parser when the start tag of an 
117
   * element is detected. Used in this context to parse and store
118
   * the acl information in class variables.
119
   */
120
  public void startElement (String uri, String localName, 
121
                            String qName, Attributes atts) 
122
         throws SAXException 
123
  {
124
    BasicNode currentNode = new BasicNode(localName);
125
    if (atts != null) {
126
      int len = atts.getLength();
127
      for (int i = 0; i < len; i++) {
128
        currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i));
129
      }
130
    }
131
    elementStack.push(currentNode); 
132
  }
133

    
134
  /**
135
   * callback method used by the SAX Parser when the text sequences of an 
136
   * xml stream are detected. Used in this context to parse and store
137
   * the acl information in class variables.
138
   */
139
  public void characters(char ch[], int start, int length)
140
         throws SAXException 
141
  {
142
    String inputString = new String(ch, start, length);
143
    BasicNode currentNode = (BasicNode)elementStack.peek(); 
144
    String currentTag = currentNode.getTagName();
145

    
146
    if (currentTag.equals("groupName")) {
147
      principal_name = inputString;
148
      principal_type = "group";
149
    } else if (currentTag.equals("userName")) {
150
      principal_name = inputString;
151
      principal_type = "user";
152
    } else if (currentTag.equals("permission")) {
153
      if ( inputString.trim().toUpperCase().equals("READ") ) {
154
        permission = permission | READ;
155
      } else if ( inputString.trim().toUpperCase().equals("WRITE") ) {
156
        permission = permission | WRITE;
157
      } else if ( inputString.trim().toUpperCase().equals("ALL") ) {
158
        permission = permission | ALL;
159
      }
160
    } else if (currentTag.equals("duration") && 
161
               begin_time == null && end_time == null ) {
162
      try {
163
        begin_time = inputString.substring(0, inputString.indexOf(" "));
164
        end_time = inputString.substring(inputString.indexOf(" ")+1);
165
      } catch (StringIndexOutOfBoundsException se) {
166
        begin_time = inputString;
167
      }
168
    } else if (currentTag.equals("count") && count == 0 ) {
169
      count = (new Integer(inputString.trim())).intValue();
170
    }
171
  }
172

    
173
  /**
174
   * callback method used by the SAX Parser when the end tag of an 
175
   * element is detected. Used in this context to parse and store
176
   * the acl information in class variables.
177
   */
178
  public void endElement (String uri, String localName, String qName)
179
         throws SAXException 
180
  {
181
    BasicNode leaving = (BasicNode)elementStack.pop(); 
182
    if ( leaving.getTagName().equals("allow") && permission > 0 ) {
183
      // collect allowed permissions in a Vector variable allow
184
      allow.add(new Integer(permission));
185
      begin1.add(begin_time);
186
      end1.add(end_time);
187
      count1.add(new Integer(count));
188

    
189
      // reset the allowed permission
190
      permission = 0;
191
      begin_time = null;
192
      end_time = null;
193
      count = 0;
194
    
195
    } else if ( leaving.getTagName().equals("deny") && permission > 0 ) {
196
      // collect denied permissions in a Vector variable denyv
197
      denyv.add(new Integer(permission));
198
      begin2.add(begin_time);
199
      end2.add(end_time);
200
      count2.add(new Integer(count));
201

    
202
      // reset the denied permission
203
      permission = 0;
204
      begin_time = null;
205
      end_time = null;
206
      count = 0;
207

    
208
    } else if ( leaving.getTagName().equals("accessControl") ) {
209
      // when order attribute for <accessControl> is specified to "denyFirst"
210
      // exclude the allowed permissions from the list of denied ones
211
      if ( leaving.getAttribute("order").equals("denyFirst") ) {
212
        for ( int i = 0; i < allow.size(); i++ ) {
213
          for ( int j = 0; j < denyv.size(); j++ ) {
214
            denyv.setElementAt( 
215
            new Integer(((Integer)denyv.elementAt(j)).intValue() & 
216
                        ~((Integer)allow.elementAt(i)).intValue()), j);
217
          }
218
        }
219
      }
220

    
221
      // insert into db connection collected permissions for the principal
222
      try {
223
        insertPermissions();
224
      } catch (SQLException sqle) {
225
        throw new SAXException(sqle);
226
      }
227

    
228
      // reset the list of allowed and denied permissions 
229
      // for use for the next principal
230
      allow  = new Vector();
231
      begin1 = new Vector();
232
      end1   = new Vector();
233
      count1 = new Vector();
234

    
235
      denyv  = new Vector();
236
      begin2 = new Vector();
237
      end2   = new Vector();
238
      count2 = new Vector();
239

    
240
    } else if ( leaving.getTagName().equals("user") || 
241
                leaving.getTagName().equals("group") ) {
242
//      try {                  
243
//        principal_name = 
244
//        principal_name.substring(0, principal_name.lastIndexOf("."));
245
//      } catch (StringIndexOutOfBoundsException se) {
246
        // reset the name of the current principal for next use
247
        principal_name = "";
248
//      }
249
    }
250
  }
251
                          
252
  /** Insert into db connection collected permissions for a principal */
253
  private void insertPermissions() 
254
          throws SQLException 
255
  {
256
    PreparedStatement pstmt;
257
    // 
258
    try {
259
      pstmt = conn.prepareStatement(
260
              "INSERT INTO xml_access " + 
261
              "(docid, principal_name, principal_type, " +
262
              "permission, begin_time, end_time, ticket_counter, deny)" +
263
              "VALUES (?, ?, ?, ?, to_date(?,'mm/dd/yy'), " +
264
              " to_date(?,'mm/dd/yy'), ?, ?)");
265
      // Bind the values to the query
266
      pstmt.setString(1, docid);
267
      pstmt.setString(2, principal_name);
268
      pstmt.setString(3, principal_type);
269
      // insert the allowed permissions first
270
      for ( int i = 0; i < allow.size(); i++ ) {
271
        pstmt.setInt(4, ((Integer)allow.elementAt(i)).intValue());
272
        pstmt.setString(5, (String)begin1.elementAt(i));
273
        pstmt.setString(6, (String)end1.elementAt(i));
274
        if ( ((Integer)count1.elementAt(i)).intValue() > 0 ) {
275
          pstmt.setString(7, "" + ((Integer)count1.elementAt(i)).intValue());
276
        } else {
277
          pstmt.setString(7, "");
278
        }
279
        pstmt.setString(8, "");
280

    
281
        pstmt.execute();
282
      }
283

    
284
      // insert the denied permissions
285
      for ( int i = 0; i < denyv.size(); i++ ) {
286
        if ( ((Integer)denyv.elementAt(i)).intValue() <= 0 ) {
287
          continue;
288
        }
289
        pstmt.setInt(4, ((Integer)denyv.elementAt(i)).intValue());
290
        pstmt.setString(5, (String)begin2.elementAt(i));
291
        pstmt.setString(6, (String)end2.elementAt(i));
292
        if ( ((Integer)count2.elementAt(i)).intValue() > 0 ) {
293
          pstmt.setString(7, "" + ((Integer)count2.elementAt(i)).intValue());
294
        } else {
295
          pstmt.setString(7, "");
296
        }
297
        pstmt.setString(8, "" + 1);
298

    
299
        pstmt.execute();
300
      }
301

    
302
    } catch (SQLException e) {
303
      throw new 
304
      SQLException("AccessControlList.insertPermissions(): " + e.getMessage());
305
    }
306
  }
307
   
308
}
(1-1/36)