Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that implements utility methods for a metadata catalog
4
 *  Copyright: 2009 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Michael Daigle
7
 *
8
 *   '$Author: daigle $'
9
 *     '$Date: 2009-08-04 14:32:58 -0700 (Tue, 04 Aug 2009) $'
10
 * '$Revision: 5015 $'
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.util;
28

    
29
import java.io.PrintWriter;
30
import java.sql.SQLException;
31
import java.util.Hashtable;
32
import java.util.Stack;
33
import java.util.Vector;
34

    
35
import javax.servlet.http.HttpServletRequest;
36
import javax.servlet.http.HttpServletResponse;
37

    
38
import org.apache.log4j.Logger;
39

    
40
import edu.ucsb.nceas.dbadapter.AbstractDatabase;
41
import edu.ucsb.nceas.metacat.DBSAXHandler;
42
import edu.ucsb.nceas.metacat.McdbException;
43
import edu.ucsb.nceas.metacat.NodeRecord;
44
import edu.ucsb.nceas.metacat.PermissionController;
45
import edu.ucsb.nceas.metacat.properties.PropertyService;
46
import edu.ucsb.nceas.metacat.service.SessionService;
47
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
48
import edu.ucsb.nceas.metacat.util.SessionData;
49
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
50
import edu.ucsb.nceas.utilities.ParseLSIDException;
51
import edu.ucsb.nceas.utilities.LSIDUtil;
52

    
53
/**
54
 * A suite of utility classes for the metadata catalog server
55
 */
56
public class DocumentUtil
57
{
58
	
59
    public static AbstractDatabase dbAdapter;
60
    
61
    private static Logger logMetacat = Logger.getLogger(DocumentUtil.class);
62
    private static char separator = '.';
63

    
64
    static {
65
        try {
66
        	separator = PropertyService.getProperty("document.accNumSeparator").charAt(0);
67
        } catch (PropertyNotFoundException pnfe) {
68
        	logMetacat.error("DocumentUtil() - Could not retrieve account number separator. " 
69
        			+ "Separator set to '.' : " + pnfe.getMessage());
70
        }
71
    }
72

    
73
    /**
74
     * Get docid from online/url string
75
     */
76
    public static String getDocIdWithRevFromOnlineURL(String url)
77
    {
78
        String docid = null;
79
        String DOCID = "docid";
80
        boolean find = false;
81
        char limited = '&';
82
        int count = 0; //keep track how many & was found
83
        Vector list = new Vector();// keep index number for &
84
        if (url == null) {
85
            logMetacat.debug("DocumentUtil.getDocIdWithRevFromOnlineURL - url is null and null will be returned");
86
            return docid;
87
        }
88
        // the first element in list is 0
89
        list.add(new Integer(0));
90
        for (int i = 0; i < url.length(); i++) {
91
            if (url.charAt(i) == limited) {
92
                // count plus 1
93
                count++;
94
                list.add(new Integer(i));
95
                // get substring beween two &
96
                String str = url.substring(
97
                        ((Integer) list.elementAt(count - 1)).intValue(), i);
98
                logMetacat.debug("DocumentUtil.getDocIdWithRevFromOnlineURL - substring between two & is: " + str);
99
                //if the subString contains docid, we got it
100
                if (str.indexOf(DOCID) != -1) {
101
                    //get index of '="
102
                    int start = getIndexForGivenChar(str, '=') + 1;
103
                    int end = str.length();
104
                    docid = str.substring(start, end);
105
                    find = true;
106
                }//if
107
            }//if
108
        }//for
109
        //if not find, we need check the subtring between the index of last &
110
        // and
111
        // the end of string
112
        if (!find) {
113
            logMetacat.debug("DocumentUtil.getDocIdWithRevFromOnlineURL - Checking the last substring");
114
            String str = url.substring(((Integer) list.elementAt(count))
115
                    .intValue() + 1, url.length());
116
            logMetacat.debug("DocumentUtil.getDocIdWithRevFromOnlineURL - Last substring is: " + str);
117
            if (str.indexOf(DOCID) != -1) {
118
                //get index of '="
119
                int start = getIndexForGivenChar(str, '=') + 1;
120
                int end = str.length();
121
                docid = str.substring(start, end);
122
                find = true;
123
            }//if
124
        }//if
125
        logMetacat.debug("DocumentUtil.getDocIdWithRevFromOnlineURL - The docid from online url is:" + docid);
126
        return docid.trim();
127
    }
128

    
129

    
130
    /**
131
     * Eocgorid identifier will look like: ecogrid://knb/tao.1.1
132
     * The AccessionNumber tao.1.1 will be returned. If the given doesn't
133
     * contains ecogrid, null will be returned.
134
     * @param identifier String
135
     * @return String
136
     */
137
    public static String getAccessionNumberFromEcogridIdentifier(String identifier)
138
    {
139
      String accessionNumber = null;
140
      if (identifier != null && identifier.startsWith(DBSAXHandler.ECOGRID))
141
      {
142
        // find the last "/" in identifier
143
        int indexOfLastSlash = identifier.lastIndexOf("/");
144
        int start = indexOfLastSlash+1;
145
        int end   = identifier.length();
146
        accessionNumber = identifier.substring(start, end);
147
      }
148
      logMetacat.warn("DocumentUtil.getAccessionNumberFromEcogridIdentifier - The accession number from url is " +
149
                                 accessionNumber);
150
      return accessionNumber;
151
    }
152

    
153
    private static int getIndexForGivenChar(String str, char character)
154
    {
155
        int index = -1;
156
        // make sure str is not null
157
        if (str == null) {
158
            logMetacat.debug("DocumentUtil.getIndexForGivenChar - " +
159
                    "The given str is null and -1 will be returned");
160
            return index;
161
        }
162
        // got though the string
163
        for (int i = 0; i < str.length(); i++) {
164
            // find the first one then break the loop
165
            if (str.charAt(i) == character) {
166
                index = i;
167
                break;
168
            }//if
169
        }//for
170
        logMetacat.info("DocumentUtil.getIndexForGivenChar - the index for char " + 
171
        		character + " is: " + index);
172
        return index;
173
    }
174

    
175
    /**
176
     * Utility method to get docid from a given string
177
     *
178
     * @param string, the given string should be these two format: 1) str1.str2
179
     *            in this case docid= str1.str2 2) str1.str2.str3, in this case
180
     *            docid =str1.str2
181
     * @param the sperator char
182
     */
183
    public static String getDocIdFromString(String str)
184
    {
185
        String docId = null;
186
        if (str == null) {
187
            logMetacat.debug(
188
                    "DocumentUtil.getDocIdFromString - The given str is null and null will be returned"
189
                            + " in getDocIdfromString");
190
            return docId;
191
        } //make sure docid is not null
192
        int dotNumber = 0;//count how many dots in given string
193
        int indexOfLastDot = 0;
194

    
195
        for (int i = 0; i < str.length(); i++) {
196
            if (str.charAt(i) == separator) {
197
                dotNumber++;//count how many dots
198
                indexOfLastDot = i;//keep the last dot postion
199
            }
200
        }//for
201

    
202
        //The string formatt is wrong, because it has more than two or less
203
        // than
204
        //one seperator
205
        if (dotNumber > 2 || dotNumber < 1) {
206
            docId = null;
207
        } else if (dotNumber == 2) //the case for str1.str2.str3
208
        {
209
            docId = str.substring(0, indexOfLastDot);
210
        } else if (dotNumber == 1) //the case for str1.str2
211
        {
212
            docId = str;
213
        }
214

    
215
        return docId;
216
    }//getDocIdFromString
217

    
218
    /**
219
     * Utility method to get version number from a given string
220
     *
221
     * @param string, the given string should be these two format: 1)
222
     *            str1.str2(no version) version =-1; 2) str1.str2.str3, in this
223
     *            case version = str3; 3) other, vresion =-2
224
     */
225
    public static int getVersionFromString(String str)
226
            throws NumberFormatException
227
    {
228
        int version = -1;
229
        String versionString = null;
230
        int dotNumber = 0;//count how many dots in given string
231
        int indexOfLastDot = 0;
232

    
233
        for (int i = 0; i < str.length(); i++) {
234
            if (str.charAt(i) == separator) {
235
                dotNumber++;//count how many dots
236
                indexOfLastDot = i;//keep the last dot postion
237
            }
238
        }//for
239

    
240
        //The string formatt is wrong, because it has more than two or less
241
        // than
242
        //one seperator
243
        if (dotNumber > 2 || dotNumber < 1) {
244
            version = -2;
245
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1)))
246
        //the case for str1.str2.str3
247
        {
248
            versionString = str.substring((indexOfLastDot + 1), str.length());
249
            version = Integer.parseInt(versionString);
250
        } else if (dotNumber == 1) //the case for str1.str2
251
        {
252
            version = -1;
253
        }
254

    
255
        return version;
256
    }//getVersionFromString
257

    
258
    /**
259
     * Utility method to get version string from a given string
260
     *
261
     * @param string, the given string should be these two format: 1)
262
     *            str1.str2(no version) version=null; 2) str1.str2.str3, in
263
     *            this case version = str3; 3) other, vresion =null;
264
     */
265
    public static String getRevisionStringFromString(String str)
266
            throws NumberFormatException
267
    {
268
        // String to store the version
269
        String versionString = null;
270
        int dotNumber = 0;//count how many dots in given string
271
        int indexOfLastDot = 0;
272

    
273
        for (int i = 0; i < str.length(); i++) {
274
            if (str.charAt(i) == separator) {
275
                dotNumber++;//count how many dots
276
                indexOfLastDot = i;//keep the last dot postion
277
            }
278
        }//for
279

    
280
        //The string formatt is wrong, because it has more than two or less
281
        // than
282
        //one seperator
283
        if (dotNumber > 2 || dotNumber < 1) {
284
            versionString = null;
285
        } else if (dotNumber == 2 && (indexOfLastDot != (str.length() - 1))) {
286
            //the case for str1.str2.str3
287
            // indexOfLastDot != (str.length() -1) means get rid of str1.str2.
288
            versionString = str.substring((indexOfLastDot + 1), str.length());
289
        } else if (dotNumber == 1) //the case for str1.str2 or str1.str2.
290
        {
291
            versionString = null;
292
        }
293

    
294
        return versionString;
295
    }//getVersionFromString
296

    
297
    /**
298
     * This method will get docid from an AccessionNumber. There is no
299
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
300
     * we think the docid will be get rid of last part
301
     */
302
    public static String getDocIdFromAccessionNumber(String accessionNumber)
303
    {
304
        String docid = null;
305
        if (accessionNumber == null) { return docid; }
306
        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
307
        docid = accessionNumber.substring(0, indexOfLastSeperator);
308
        logMetacat.debug("DocumentUtil.getDocIdFromAccessionNumber - after parsing accession number, docid is "
309
                + docid);
310
        return docid;
311
    }
312

    
313
    /**
314
     * This method will get inline data id without the revision number.
315
     * So if inlineData.1.2 is passed as input, inlineData.2 is returned.
316
     */
317
    public static String getInlineDataIdWithoutRev(String accessionNumber)
318
    {
319
        String docid = null;
320
        if (accessionNumber == null) { return docid; }
321
        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
322
        String version = accessionNumber.substring(indexOfLastSeperator,
323
                                                   accessionNumber.length());
324
        accessionNumber = accessionNumber.substring(0, indexOfLastSeperator);
325
        indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
326
        docid = accessionNumber.substring(0, indexOfLastSeperator) + version;
327
        logMetacat.debug("DocumentUtil.getInlineDataIdWithoutRev - after parsing accessionnumber, docid is "
328
                                 + docid);
329

    
330
        return docid;
331
    }
332

    
333
    /**
334
     * This method will call both getDocIdFromString and
335
     * getDocIdFromAccessionNumber. So first, if the string looks str1.str2,
336
     * the docid will be str1.str2. If the string is str1.str2.str3, the docid
337
     * will be str1.str2. If the string is str1.str2.str3.str4 or more, the
338
     * docid will be str1.str2.str3. If the string look like str1, null will be
339
     * returned
340
     *
341
     */
342
    public static String getSmartDocId(String str)
343
    {
344
        String docid = null;
345
        //call geDocIdFromString first.
346
        docid = getDocIdFromString(str);
347
        // If docid is null, try to call getDocIdFromAccessionNumber
348
        // it will handle the seperator more than2
349
        if (docid == null) {
350
            docid = getDocIdFromAccessionNumber(str);
351
        }
352
        logMetacat.debug("DocumentUtil.getSmartDocId - The docid get from smart docid getor is "
353
                + docid);
354
        return docid;
355
    }
356

    
357
    /**
358
     * This method will get revision from an AccessionNumber. There is no
359
     * assumption the accessnumber will be str1.str2.str3. It can be more. So
360
     * we think the docid will be get rid of last part
361
     */
362
    public static int getRevisionFromAccessionNumber(String accessionNumber)
363
            throws NumberFormatException
364
    {
365
        String rev = null;
366
        int revNumber = -1;
367
        if (accessionNumber == null) { return revNumber; }
368
        int indexOfLastSeperator = accessionNumber.lastIndexOf(separator);
369
        rev = accessionNumber.substring(indexOfLastSeperator + 1,
370
                accessionNumber.length());
371
        revNumber = Integer.parseInt(rev);
372
        logMetacat.debug("DocumentUtil.getRevisionFromAccessionNumber - after parsing accessionnumber, rev is "
373
                + revNumber);
374
        return revNumber;
375
    }
376

    
377
    /**
378
     * Method to get docidwithrev from eml2 inline data id The eml inline data
379
     * id would look like eml.200.2.3
380
     */
381
    public static String getDocIdWithoutRevFromInlineDataID(String inlineDataID)
382
    {
383
        String docidWithoutRev = null;
384
        if (inlineDataID == null) { return docidWithoutRev; }
385
        char charSeperator = separator;
386
        int targetNumberOfSeperator = 2;// we want to know his index
387
        int numberOfSeperator = 0;
388
        for (int i = 0; i < inlineDataID.length(); i++) {
389
            // meet seperator, increase number of seperator
390
            if (inlineDataID.charAt(i) == charSeperator) {
391
                numberOfSeperator++;
392
            }
393
            // if number of seperator reach the target one, record the index(i)
394
            // and get substring and terminate the loop
395
            if (numberOfSeperator == targetNumberOfSeperator) {
396
                docidWithoutRev = inlineDataID.substring(0, i);
397
                break;
398
            }
399
        }
400

    
401
        logMetacat.debug("DocumentUtil.getDocIdWithoutRevFromInlineDataID - Docid without rev from inlinedata id: "
402
                + docidWithoutRev);
403
        return docidWithoutRev;
404

    
405
    }
406
    
407
    /**
408
     * Revise stack change a stack to opposite order
409
     */
410
    public static Stack<NodeRecord> reviseStack(Stack<NodeRecord> stack)
411
    {
412
        Stack result = new Stack();
413
        // make sure the parameter is correct
414
        if (stack == null || stack.isEmpty()) {
415
            result = stack;
416
            return result;
417
        }
418

    
419
        while (!stack.isEmpty()) {
420
            Object obj = stack.pop();
421
            result.push(obj);
422
        }
423
        return result;
424
    }
425
    
426
    public static void isAuthorized(PrintWriter out, Hashtable<String,String[]> params, 
427
    		HttpServletRequest request, HttpServletResponse response) throws MetacatUtilException {
428
    	
429
    	String resourceLsid;
430
    	String[] resourceLsids = params.get("resourceLsid");
431
    	if (resourceLsids == null) {
432
    		throw new MetacatUtilException("DocumentUtil.isAuthorized - " + 
433
    				"resourceLsid parameter cannot be null.");
434
    	}
435
    	resourceLsid = resourceLsids[0];
436
    	 
437
    	String permission;
438
    	String[] permissions = params.get("permission");
439
    	if (permissions == null) {
440
    		throw new MetacatUtilException("DocumentUtil.isAuthorized - " + 
441
    				"permission parameter cannot be null.");
442
    	}
443
    	permission = permissions[0];
444
    	
445
    	String sessionId;
446
    	String[] sessionIds = params.get("sessionId");
447
    	if (sessionIds == null) {
448
    		throw new MetacatUtilException("DocumentUtil.isAuthorized - " + 
449
    				"sessionId parameter cannot be null.");
450
    	}
451
    	sessionId = sessionIds[0];
452
    	
453
    	String isAuthorized = "false";
454
    	String message = "";
455
    	
456
    	String result = "<resourceAuthorization>";
457
    	result += "<resourceId>" + resourceLsid + "</resourceId>"; 
458
    	result += "<permission>" + permission + "</permission>";
459
    	result += "<sessionId>" + sessionId + "</sessionId>";
460

    
461
    	if (!SessionService.isSessionRegistered(sessionId)) {
462
    		message = "Session is not logged in";
463
    	} else {
464
    		SessionData sessionData = SessionService.getRegisteredSession(sessionId);
465
    		
466
    		String docId = null;
467
    		try {
468
    			docId = LSIDUtil.getDocId(resourceLsid, true);
469
    			PermissionController pc = new PermissionController(docId);   
470
    			if (pc.hasPermission(sessionData.getUserName(), sessionData.getGroupNames(), permission)) {
471
    				isAuthorized = "true";
472
    				message = " docid: " + docId + " is authorized for session";
473
    			}
474
    		} catch (ParseLSIDException ple) {
475
    			message = "unparseable resource lsid: " + ple.getMessage();
476
    		} catch (McdbException me) {
477
    			message = "could not create permission controller for docid: " + docId + " : " + me.getMessage();
478
    		} catch (SQLException sqle) {
479
    			message = "SQL error getting permissions for docid: " + docId + " : " + sqle.getMessage();
480
    		}
481
    	}
482
    	
483
    	result += "<isAuthorized>" + isAuthorized + "</isAuthorized>";
484
    	result += "<message>" + message + "</message>";
485
    	result += "</resourceAuthorization>";
486
    	
487
    	out.write(result);
488
    }
489

    
490
}
(4-4/14)