Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2011 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: leinfelder $'
7
 *     '$Date: 2011-06-30 16:31:53 -0700 (Thu, 30 Jun 2011) $'
8
 *
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
package edu.ucsb.nceas.metacat.restservice;
24

    
25
import java.io.ByteArrayInputStream;
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.io.OutputStream;
31
import java.io.PrintWriter;
32
import java.io.UnsupportedEncodingException;
33
import java.util.Date;
34
import java.util.Hashtable;
35
import java.util.Map;
36
import java.util.Timer;
37

    
38
import javax.servlet.ServletContext;
39
import javax.servlet.http.HttpServletRequest;
40
import javax.servlet.http.HttpServletResponse;
41

    
42
import org.apache.commons.fileupload.FileUploadException;
43
import org.apache.commons.io.IOUtils;
44
import org.apache.log4j.Logger;
45
import org.dataone.client.ObjectFormatCache;
46
import org.dataone.client.auth.CertificateManager;
47
import org.dataone.service.exceptions.BaseException;
48
import org.dataone.service.exceptions.IdentifierNotUnique;
49
import org.dataone.service.exceptions.InsufficientResources;
50
import org.dataone.service.exceptions.InvalidRequest;
51
import org.dataone.service.exceptions.InvalidSystemMetadata;
52
import org.dataone.service.exceptions.InvalidToken;
53
import org.dataone.service.exceptions.NotAuthorized;
54
import org.dataone.service.exceptions.NotFound;
55
import org.dataone.service.exceptions.NotImplemented;
56
import org.dataone.service.exceptions.ServiceFailure;
57
import org.dataone.service.exceptions.UnsupportedType;
58
import org.dataone.service.types.AccessPolicy;
59
import org.dataone.service.types.Checksum;
60
import org.dataone.service.types.Event;
61
import org.dataone.service.types.Identifier;
62
import org.dataone.service.types.Log;
63
import org.dataone.service.types.ObjectFormat;
64
import org.dataone.service.types.ObjectFormatIdentifier;
65
import org.dataone.service.types.ObjectFormatList;
66
import org.dataone.service.types.ObjectLocationList;
67
import org.dataone.service.types.Permission;
68
import org.dataone.service.types.Subject;
69
import org.dataone.service.types.SystemMetadata;
70
import org.jibx.runtime.JiBXException;
71

    
72
import edu.ucsb.nceas.metacat.MetacatHandler;
73
import edu.ucsb.nceas.metacat.dataone.CNodeService;
74

    
75
/**
76
 * CN REST service implementation handler
77
 * 
78
 * ******************
79
 	CNCore -- DONE
80
		create() - POST /d1/cn/object/PID
81
		listFormats() - GET /d1/cn/formats
82
		getFormat() - GET /d1/cn/formats/FMTID
83
		getLogRecords - GET /d1/cn/log
84
		reserveIdentifier() - POST /d1/cn/reserve
85
		listNodes() - Not implemented
86
		registerSystemMetadata() - POST /d1/meta/PID
87
	
88
	CNRead -- DONE
89
		get() - GET /d1/cn/object/PID
90
		getSystemMetadata() - GET /d1/cn/meta/PID
91
		resolve() - GET /d1/cn/resolve/PID
92
		assertRelation() - GET /d1/cn/assertRelation/PID
93
		getChecksum() - GET /d1/cn/checksum
94
		search() - Not implemented in Metacat
95
	
96
	CNAuthorization
97
		setOwner() - PUT /d1/cn/owner/PID
98
		isAuthorized() - GET /d1/cn/isAuthorized/PID
99
		setAccessPolicy() - POST /d1/cn/accessRules
100
		
101
	CNIdentity - not implemented at all on Metacat
102
	
103
	CNReplication
104
		setReplicationStatus() - Not exposed
105
		updateReplicationMetadata() - New method?
106
		setReplicationPolicy() - Not exposed
107
	
108
	CNRegister -- not implemented at all in Metacat
109
 * ******************
110
 * @author leinfelder
111
 *
112
 */
113
public class CNResourceHandler extends D1ResourceHandler {
114

    
115
	/** CN-specific operations **/
116
    protected static final String RESOURCE_RESERVE = "reserve";
117
    protected static final String RESOURCE_FORMATS = "formats"; //remove from super
118
    protected static final String RESOURCE_RESOLVE = "resolve";
119
    protected static final String RESOURCE_ASSERT_RELATION = "assertRelation";
120
    protected static final String RESOURCE_OWNER = "owner";
121
    protected static final String RESOURCE_NOTIFY = "notify";
122
    protected static final String RESOURCE_META_REPLICATION = "meta/replication";
123
    protected static final String RESOURCE_META_POLICY = "meta/policy";
124
	
125
    public CNResourceHandler(ServletContext servletContext,
126
			HttpServletRequest request, HttpServletResponse response) {
127
		super(servletContext, request, response);
128
        logMetacat = Logger.getLogger(CNResourceHandler.class);
129
	}
130

    
131
	/**
132
     * This function is called from REST APU servlet and handles each request to the servlet 
133
     * 
134
     * @param httpVerb (GET, POST, PUT or DELETE)
135
     */
136
    public void handle(byte httpVerb) {
137
        try {
138
            //substring off the "d1/cn/" part of the url
139
        	String resourcePrefix = RESOURCE_BASE_URL + "/cn/";
140
            String resource = request.getServletPath();
141
            resource = resource.substring(resource.indexOf(resourcePrefix) + resourcePrefix.length());
142
            resource = resource.trim();
143
                        
144
            logMetacat.debug("handling verb " + httpVerb + " request with resource '" + resource + "'");
145
            boolean status = false;
146
            
147
            // load session from certificate in request
148
            // TODO: move to superclass
149
            session = CertificateManager.getInstance().getSession(request);
150
            
151
            if (resource != null) {
152

    
153
                params = new Hashtable<String, String[]>();
154
                initParams();
155

    
156
                Timer timer = new Timer();
157
                handler = new MetacatHandler(timer);
158

    
159
                if (resource.equals(RESOURCE_ACCESS_RULES) && httpVerb == PUT) {
160
                    logMetacat.debug("Setting access policy");
161
                    setAccess();
162
                    status = true;
163
                    logMetacat.debug("done setting access");
164
                    
165
                } else if (resource.equals(RESOURCE_META)) {
166
                    logMetacat.debug("Using resource: " + RESOURCE_META);
167
                    String objectId = request.getPathInfo();
168
                    if (objectId != null && objectId.length() > 1) {
169
                        objectId = request.getPathInfo().substring(1);
170
                    }
171
                    // get
172
                    if (httpVerb == GET) {
173
                        getSystemMetadataObject(objectId);
174
                        status = true;
175
                    }
176
                    // post to register system metadata
177
                    if (httpVerb == POST) {
178
                    	registerSystemMetadata(objectId);
179
                    	status = true;
180
                    }
181

    
182
                } else if (resource.equals(RESOURCE_RESERVE)) {
183
                    // reserve the ID (in params)
184
                    if (httpVerb == POST) {
185
                    	reserve();
186
                    	status = true;
187
                    }
188
                } else if (resource.equals(RESOURCE_ASSERT_RELATION)) {
189
                	String objectId = request.getPathInfo();
190
                    if (objectId != null && objectId.length() > 1) {
191
                        objectId = request.getPathInfo().substring(1);
192
                    }
193
                    // reserve the ID (in params)
194
                    if (httpVerb == GET) {
195
                    	assertRelation(objectId);
196
                    	status = true;
197
                    }    
198
                } else if (resource.equals(RESOURCE_RESOLVE)) {
199
                	String objectId = request.getPathInfo();
200
                    if (objectId != null && objectId.length() > 1) {
201
                        objectId = request.getPathInfo().substring(1);
202
                    }
203
                    // resolve the object location
204
                    if (httpVerb == GET) {
205
                    	resolve(objectId);
206
                    	status = true;
207
                    }
208
                } else if (resource.equals(RESOURCE_OWNER)) {
209
                	String objectId = request.getPathInfo();
210
                    if (objectId != null && objectId.length() > 1) {
211
                        objectId = request.getPathInfo().substring(1);
212
                    }
213
                    // set the owner
214
                    if (httpVerb == PUT) {
215
                    	owner(objectId);
216
                    	status = true;
217
                    }    
218
                } else if (resource.equals(RESOURCE_OWNER)) {
219
                	String objectId = request.getPathInfo();
220
                    if (objectId != null && objectId.length() > 1) {
221
                        objectId = request.getPathInfo().substring(1);
222
                    }
223
                    // set the owner
224
                    if (httpVerb == PUT) {
225
                    	owner(objectId);
226
                    	status = true;
227
                    }
228
                } else if (resource.equals(RESOURCE_IS_AUTHORIZED)) {
229
                	String objectId = request.getPathInfo();
230
                    if (objectId != null && objectId.length() > 1) {
231
                        objectId = request.getPathInfo().substring(1);
232
                    }
233
                    // authorized?
234
                    if (httpVerb == GET) {
235
                    	isAuthorized(objectId);
236
                    	status = true;
237
                    }    
238
                } else if (resource.equals(RESOURCE_OBJECTS)) {
239
                    logMetacat.debug("Using resource 'object'");
240
                    logMetacat.debug("D1 Rest: Starting resource processing...");
241

    
242
                    String objectId = request.getPathInfo();
243
                    if (objectId != null && objectId.length() > 1) {
244
                        objectId = request.getPathInfo().substring(1);
245
                    }
246
                    else {
247
                        objectId = null;
248
                    }
249
                    
250
                    logMetacat.debug("objectId: " + objectId);
251
                    logMetacat.debug("verb:" + httpVerb);
252

    
253
                    if (httpVerb == GET) {
254
                        getObject(objectId);
255
                        status = true;
256
                    } else if (httpVerb == POST) {
257
                        putObject(objectId, FUNCTION_NAME_INSERT);
258
                        status = true;
259
                    } else if (httpVerb == PUT) {
260
                    	// TODO: this is not applicable for CN
261
                        putObject(objectId, FUNCTION_NAME_UPDATE);
262
                        status = true;
263
                    }
264
                    
265
                } else if (resource.equals(RESOURCE_FORMATS)) {
266
                  logMetacat.debug("Using resource: " + RESOURCE_FORMATS);
267
                  
268
                  // check for a format identifier
269
                  String fmtid = request.getPathInfo();
270
                  
271
                  if (fmtid != null && fmtid.length() > 1 ) {
272
                  	fmtid = request.getPathInfo().substring(1);
273
                  } else {
274
                  	fmtid = null;
275
                  }
276
                  
277
                  // handle each verb
278
                  if (httpVerb == GET) {
279
                  	if (fmtid == null) {
280
                  		// list the formats collection
281
                  		listFormats();
282
                  	} else {
283
                  		// get the specified format
284
                  		getFormat(fmtid);
285
                  	}
286
                  	status = true;
287
                  }
288
                  
289
                } else if (resource.equals(RESOURCE_LOG)) {
290
                    logMetacat.debug("Using resource: " + RESOURCE_LOG);
291
                    //handle log events
292
                    if (httpVerb == GET) {
293
                        getLog();
294
                        status = true;
295
                    }
296

    
297
                } else if (resource.equals(RESOURCE_CHECKSUM)) {
298
                    logMetacat.debug("Using resource: " + RESOURCE_CHECKSUM);
299
                    //handle checksum requests
300
                    if (httpVerb == GET) {
301
                    
302
                        String guid = request.getPathInfo();
303
                        if (guid != null && guid.length() > 1) {
304
                            guid = request.getPathInfo().substring(1); //trim the slash
305
                        }
306
                        checksum(guid);
307
                        status = true;
308
                    }
309
                } 
310
                    
311
                if (!status) {
312
                	throw new ServiceFailure("0000", "Unknown error, status=" + status);
313
                }
314
            } else {
315
            	throw new InvalidRequest("0000", "No resource matched for " + resource);
316
            }
317
        } catch (BaseException be) {
318
        	// report Exceptions as clearly and generically as possible
319
        	OutputStream out = null;
320
			try {
321
				out = response.getOutputStream();
322
			} catch (IOException ioe) {
323
				logMetacat.error("Could not get output stream from response", ioe);
324
			}
325
            serializeException(be, out);
326
        } catch (Exception e) {
327
            // report Exceptions as clearly and generically as possible
328
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
329
        	OutputStream out = null;
330
			try {
331
				out = response.getOutputStream();
332
			} catch (IOException ioe) {
333
				logMetacat.error("Could not get output stream from response", ioe);
334
			}
335
			ServiceFailure se = new ServiceFailure("0000", e.getMessage());
336
            serializeException(se, out);
337
        }
338
    }
339
    
340
    /**
341
     * Get the checksum for the given guid
342
     * 
343
     * @param guid
344
     * @throws NotImplemented 
345
     * @throws InvalidRequest 
346
     * @throws NotFound 
347
     * @throws NotAuthorized 
348
     * @throws ServiceFailure 
349
     * @throws InvalidToken 
350
     * @throws IOException 
351
     * @throws JiBXException 
352
     */
353
    private void checksum(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, JiBXException, IOException {
354
    	Identifier guidid = new Identifier();
355
        guidid.setValue(guid);
356
        logMetacat.debug("getting checksum for object " + guid);
357
        Checksum c = CNodeService.getInstance().getChecksum(session, guidid);
358
        logMetacat.debug("got checksum " + c.getValue());
359
        response.setStatus(200);
360
        logMetacat.debug("serializing response");
361
        serializeServiceType(Checksum.class, c, response.getOutputStream());
362
        logMetacat.debug("done serializing response.");
363
        
364
    }
365
    
366
	/**
367
     * get the logs from the CrudService based on passed params.  Available 
368
     * params are token, fromDate, toDate, event.  See 
369
     * http://mule1.dataone.org/ArchitectureDocs/mn_api_crud.html#MN_crud.getLogRecords
370
     * for more info
371
	 * @throws NotImplemented 
372
	 * @throws InvalidRequest 
373
	 * @throws NotAuthorized 
374
	 * @throws ServiceFailure 
375
	 * @throws InvalidToken 
376
	 * @throws IOException 
377
	 * @throws JiBXException 
378
     */
379
    private void getLog() throws InvalidToken, ServiceFailure, NotAuthorized, InvalidRequest, NotImplemented, IOException, JiBXException
380
    {
381
        
382
        Date fromDate = null;
383
        Date toDate = null;
384
        Event event = null;
385
        Integer start = null;
386
        Integer count = null;
387
        
388
        try {
389
        	String fromDateS = params.get("fromDate")[0];
390
            System.out.println("param fromDateS: " + fromDateS);
391
            fromDate = parseDateAndConvertToGMT(fromDateS);
392
        } catch (Exception e) {
393
        	logMetacat.warn("Could not parse fromDate: " + e.getMessage());
394
        }
395
        try {
396
        	String toDateS = params.get("toDate")[0];
397
            System.out.println("param toDateS: " + toDateS);
398
            toDate = parseDateAndConvertToGMT(toDateS);
399
        } catch (Exception e) {
400
        	logMetacat.warn("Could not parse toDate: " + e.getMessage());
401
		}
402
        try {
403
        	String eventS = params.get("event")[0];
404
            event = Event.convert(eventS);
405
        } catch (Exception e) {
406
        	logMetacat.warn("Could not parse event: " + e.getMessage());
407
		}
408
        System.out.println("fromDate: " + fromDate + " toDate: " + toDate);
409
        
410
        try {
411
        	start =  Integer.parseInt(params.get("start")[0]);
412
        } catch (Exception e) {
413
			logMetacat.warn("Could not parse start: " + e.getMessage());
414
		}
415
        try {
416
        	count =  Integer.parseInt(params.get("count")[0]);
417
        } catch (Exception e) {
418
			logMetacat.warn("Could not parse count: " + e.getMessage());
419
		}
420
        
421
        System.out.println("calling getLogRecords");
422
        Log log = CNodeService.getInstance().getLogRecords(session, fromDate, toDate, event, start, count);
423
        
424
        OutputStream out = response.getOutputStream();
425
        response.setStatus(200);
426
        response.setContentType("text/xml");
427
        
428
        serializeServiceType(Log.class, log, out);
429
  
430
    }
431

    
432
    /**
433
     * Implements REST version of DataONE CRUD API --> get
434
     * @param guid ID of data object to be read
435
     * @throws NotImplemented 
436
     * @throws InvalidRequest 
437
     * @throws NotFound 
438
     * @throws NotAuthorized 
439
     * @throws ServiceFailure 
440
     * @throws InvalidToken 
441
     * @throws IOException 
442
     */
443
    protected void getObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException {
444

    
445
        
446
        if (guid != null) { //get a specific document                
447
            Identifier id = new Identifier();
448
            id.setValue(guid);
449
                
450
            SystemMetadata sm = CNodeService.getInstance().getSystemMetadata(session, id);
451
            
452
            //set the content type
453
            if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
454
            		ObjectFormatCache.getInstance().getFormat("text/csv").getFmtid().getValue()))
455
            {
456
                response.setContentType("text/csv");
457
                response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".csv");
458
            }
459
            else if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
460
            		ObjectFormatCache.getInstance().getFormat("text/plain").getFmtid().getValue()))
461
            {
462
                response.setContentType("text/plain");
463
                response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".txt");
464
            } 
465
            else if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
466
            		ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFmtid().getValue()))
467
            {
468
                response.setContentType("application/octet-stream");
469
            }
470
            else
471
            {
472
                response.setContentType("text/xml");
473
                response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".xml");
474
            }
475
            
476
            InputStream data = CNodeService.getInstance().get(session, id);
477
            
478
            OutputStream out = response.getOutputStream();
479
            response.setStatus(200);
480
            IOUtils.copyLarge(data, out);
481

    
482
        }
483
            
484
    }
485
    
486

    
487
    /**
488
     * Implements REST version of DataONE CRUD API --> getSystemMetadata
489
     * @param guid ID of data object to be read
490
     * @throws NotImplemented 
491
     * @throws InvalidRequest 
492
     * @throws NotFound 
493
     * @throws NotAuthorized 
494
     * @throws ServiceFailure 
495
     * @throws InvalidToken 
496
     * @throws IOException 
497
     * @throws JiBXException 
498
     */
499
    protected void getSystemMetadataObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException, JiBXException {
500

    
501
        Identifier id = new Identifier();
502
        id.setValue(guid);
503
        SystemMetadata sysmeta = CNodeService.getInstance().getSystemMetadata(session, id);
504
        
505
        response.setContentType("text/xml");
506
        response.setStatus(200);
507
        OutputStream out = response.getOutputStream();
508
        
509
        // Serialize and write it to the output stream
510
       serializeServiceType(SystemMetadata.class, sysmeta, out);
511
   }
512
    
513
    /**
514
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler > handleInsertOrUpdateAction 
515
     * 
516
     * @param guid - ID of data object to be inserted or updated.  If action is update, the pid
517
     *               is the existing pid.  If insert, the pid is the new one
518
     * @throws InvalidRequest 
519
     * @throws ServiceFailure 
520
     * @throws IdentifierNotUnique 
521
     * @throws JiBXException 
522
     * @throws NotImplemented 
523
     * @throws InvalidSystemMetadata 
524
     * @throws InsufficientResources 
525
     * @throws UnsupportedType 
526
     * @throws NotAuthorized 
527
     * @throws InvalidToken 
528
     * @throws IOException 
529
     */
530
    protected void putObject(String pid, String action) throws ServiceFailure, InvalidRequest, IdentifierNotUnique, JiBXException, InvalidToken, NotAuthorized, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, IOException {
531
        logMetacat.debug("Entering putObject: " + pid + "/" + action);
532
        
533
        // Read the incoming data from its Mime Multipart encoding
534
    	Map<String, File> files = collectMultipartFiles();
535
        InputStream object = null;
536
        InputStream sysmeta = null;
537

    
538
        File smFile = files.get("sysmeta");
539
        sysmeta = new FileInputStream(smFile);
540
        File objFile = files.get("object");
541
        object = new FileInputStream(objFile);
542
       
543
        if (action.equals(FUNCTION_NAME_INSERT)) { //handle inserts
544

    
545
            logMetacat.debug("Commence creation...");
546
            SystemMetadata smd = (SystemMetadata) deserializeServiceType(SystemMetadata.class, sysmeta);
547

    
548
            Identifier id = new Identifier();
549
            id.setValue(pid);
550
            logMetacat.debug("creating object with pid " + id.getValue());
551
            Identifier rId = CNodeService.getInstance().create(session, id, object, smd);
552
            
553
            OutputStream out = response.getOutputStream();
554
            response.setStatus(200);
555
            response.setContentType("text/xml");
556
            
557
            serializeServiceType(Identifier.class, rId, out);
558
            
559
        } else {
560
            throw new InvalidRequest("1000", "Operation must be create.");
561
        }
562
    }
563

    
564
    /**
565
     * List the object formats registered with the system
566
     * @throws NotImplemented 
567
     * @throws InsufficientResources 
568
     * @throws NotFound 
569
     * @throws ServiceFailure 
570
     * @throws InvalidRequest 
571
     * @throws IOException 
572
     * @throws JiBXException 
573
     */
574
	private void listFormats() throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
575
      logMetacat.debug("Entering listFormats()");
576

    
577
      ObjectFormatList objectFormatList = CNodeService.getInstance().listFormats();
578
      // get the response output stream
579
      OutputStream out = response.getOutputStream();
580
      response.setStatus(200);
581
      response.setContentType("text/xml");
582
      
583
      serializeServiceType(ObjectFormatList.class, objectFormatList, out);
584
            
585
    }
586

    
587
		/**
588
     * Return the requested object format
589
     * 
590
     * @param fmtidStr the requested format identifier as a string
591
		 * @throws NotImplemented 
592
		 * @throws InsufficientResources 
593
		 * @throws NotFound 
594
		 * @throws ServiceFailure 
595
		 * @throws InvalidRequest 
596
		 * @throws IOException 
597
		 * @throws JiBXException 
598
     */
599
    private void getFormat(String fmtidStr) throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
600
      logMetacat.debug("Entering listFormats()");
601
      
602
      ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
603
      fmtid.setValue(fmtidStr);
604
      
605
	  // get the specified object format
606
      ObjectFormat objectFormat = CNodeService.getInstance().getFormat(fmtid);
607
      
608
      OutputStream out = response.getOutputStream();
609
      response.setStatus(200);
610
      response.setContentType("text/xml");
611
      
612
      serializeServiceType(ObjectFormat.class, objectFormat, out);
613
      
614
    }
615
    
616
    /**
617
     * Reserve the given Identifier
618
     * @throws InvalidToken
619
     * @throws ServiceFailure
620
     * @throws NotAuthorized
621
     * @throws IdentifierNotUnique
622
     * @throws NotImplemented
623
     * @throws InvalidRequest
624
     * @throws IOException 
625
     * @throws JiBXException 
626
     */
627
    private void reserve() throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest, IOException, JiBXException {
628
    	String id = params.get("pid")[0];
629
    	String format = params.get("format")[0];
630
		String scope = params.get("scope")[0];
631
		Identifier pid = new Identifier();
632
		pid.setValue(id);
633
		Identifier retPid = CNodeService.getInstance().reserveIdentifier(session, pid, scope, format);
634
		OutputStream out = response.getOutputStream();
635
		response.setStatus(200);
636
		response.setContentType("text/xml");
637
		serializeServiceType(Identifier.class, retPid, out);
638
		
639
    }
640
    
641
    /**
642
     * 
643
     * @param id
644
     * @throws InvalidRequest
645
     * @throws InvalidToken
646
     * @throws ServiceFailure
647
     * @throws NotAuthorized
648
     * @throws NotFound
649
     * @throws NotImplemented
650
     * @throws IOException
651
     * @throws JiBXException 
652
     */
653
    private void resolve(String id) throws InvalidRequest, InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, IOException, JiBXException {
654
		Identifier pid = new Identifier();
655
		pid.setValue(id);
656
		ObjectLocationList locationList = CNodeService.getInstance().resolve(session, pid);
657
	    OutputStream out = response.getOutputStream();
658
		response.setStatus(200);
659
		response.setContentType("text/xml");
660
		serializeServiceType(ObjectLocationList.class, locationList, out);
661
		
662
    }
663

    
664
    /**
665
     * Assert that a relationship exists between two resources
666
     * @param id
667
     * @return
668
     * @throws InvalidToken
669
     * @throws ServiceFailure
670
     * @throws NotAuthorized
671
     * @throws NotFound
672
     * @throws InvalidRequest
673
     * @throws NotImplemented
674
     */
675
    private boolean assertRelation(String id) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented {
676
		Identifier pidOfSubject = new Identifier();
677
		pidOfSubject.setValue(id);
678
		String relationship = null;
679
		try {
680
			relationship = params.get("relationship")[0];
681
		} catch (Exception e) {
682
			logMetacat.warn("relationship not specified");
683
		}
684
		Identifier pidOfObject = new Identifier();
685
		try {
686
			String objPid = params.get("pidOfObject")[0];
687
			pidOfObject.setValue(objPid);
688
		} catch (Exception e) {
689
			logMetacat.warn("pidOfObject not specified");
690
		}
691
		boolean result = CNodeService.getInstance().assertRelation(session, pidOfSubject, relationship, pidOfObject);
692
		response.setStatus(200);
693
		response.setContentType("text/xml");
694
		return result;
695
    }
696
    
697
    /**
698
     * Set the owner of a resource
699
     * @param id
700
     * @throws JiBXException
701
     * @throws InvalidToken
702
     * @throws ServiceFailure
703
     * @throws NotFound
704
     * @throws NotAuthorized
705
     * @throws NotImplemented
706
     * @throws InvalidRequest
707
     * @throws IOException
708
     */
709
    private void owner(String id) throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException {
710
		Identifier pid = new Identifier();
711
		pid.setValue(id);
712
		String subjectStr = params.get("subject")[0];
713
		Subject subject = (Subject) deserializeServiceType(Subject.class, new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
714
		Identifier retPid = CNodeService.getInstance().setOwner(session, pid, subject);
715
		OutputStream out = response.getOutputStream();
716
		response.setStatus(200);
717
		response.setContentType("text/xml");
718
		serializeServiceType(Identifier.class, retPid, out);		
719
    }
720
    
721
    /**
722
     * Processes the authorization check for given id
723
     * @param id
724
     * @return
725
     * @throws ServiceFailure
726
     * @throws InvalidToken
727
     * @throws NotFound
728
     * @throws NotAuthorized
729
     * @throws NotImplemented
730
     * @throws InvalidRequest
731
     */
732
    private boolean isAuthorized(String id) throws ServiceFailure, InvalidToken, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
733
		Identifier pid = new Identifier();
734
		pid.setValue(id);
735
		String permission = params.get("permission")[0];
736
		boolean result = CNodeService.getInstance().isAuthorized(session, pid, Permission.valueOf(permission));
737
		response.setStatus(200);
738
		response.setContentType("text/xml");
739
		return result;
740
    }
741
    
742
    /**
743
     * Register System Metadata without data or metadata object
744
     * @param pid identifier for System Metadata entry
745
     * @throws JiBXException 
746
     * @throws FileUploadException 
747
     * @throws IOException 
748
     * @throws InvalidRequest 
749
     * @throws ServiceFailure 
750
     * @throws InvalidSystemMetadata 
751
     * @throws NotAuthorized 
752
     * @throws NotImplemented 
753
     */
754
    protected boolean registerSystemMetadata(String pid) throws ServiceFailure, InvalidRequest, IOException, FileUploadException, JiBXException, NotImplemented, NotAuthorized, InvalidSystemMetadata {
755
		logMetacat.debug("Entering registerSystemMetadata: " + pid);
756

    
757
		// get the system metadata from the request
758
		SystemMetadata systemMetadata = collectSystemMetadata();
759

    
760
		Identifier guid = new Identifier();
761
		guid.setValue(pid);
762
		logMetacat.debug("registering system metadata with pid " + guid.getValue());
763
		boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, systemMetadata);
764
		
765
		response.setStatus(200);
766
		response.setContentType("text/xml");
767
		return result;
768
			
769
	}
770
    
771
    /**
772
     * set the access perms on a document
773
     * @throws JiBXException 
774
     * @throws UnsupportedEncodingException 
775
     * @throws InvalidRequest 
776
     * @throws NotImplemented 
777
     * @throws NotAuthorized 
778
     * @throws NotFound 
779
     * @throws ServiceFailure 
780
     * @throws InvalidToken 
781
     */
782
    protected void setAccess() throws UnsupportedEncodingException, JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
783

    
784
        String guid = params.get("guid")[0];
785
        Identifier id = new Identifier();
786
        id.setValue(guid);
787
        String accesspolicy = params.get("accesspolicy")[0];
788
        AccessPolicy accessPolicy = (AccessPolicy) deserializeServiceType(AccessPolicy.class, new ByteArrayInputStream(accesspolicy.getBytes("UTF-8")));
789
        CNodeService.getInstance().setAccessPolicy(session, id, accessPolicy);
790

    
791
    }
792
    
793
    /**
794
     * Earthgrid API > Query Service > Query Function : translates ecogrid query document to metacat query 
795
     * then calls DBQuery > createResultDocument function and then again translate resultset to ecogrid resultset
796
     * 
797
     * NOTE:
798
     *      This is the only method that uses EcoGrid classes for its implementation.  
799
     *      It does so because it takes an EcoGrid Query as input, and outputs an
800
     *      EcoGrid ResultSet document.  These documents are parsed by the auto-generated
801
     *      EcoGrid classes from axis, and so we link to them here rather than re-inventing them.
802
     *      This creates a circular dependency, because the Metacat classes are needed
803
     *      to build the EcoGrid implementation, and the EcoGrid jars are needed to build this query()
804
     *      method.  This circularity could be resolved by moving the EcoGrid classes
805
     *      to Metacat directly.  As we transition away from EcoGrid SOAP methods in
806
     *      favor of these REST interfaces, this circular dependency can be eliminated.
807
     *        
808
     * @throws Exception
809
     */
810
    private void query() throws Exception {
811
        /*  This block commented out because of the EcoGrid circular dependency.
812
         *  For now, query will not be supported until the circularity can be
813
         *  resolved, probably by moving the ecogrid query syntax transformers
814
         *  directly into the Metacat codebase.  MBJ 2010-02-03
815
         
816
        try {
817
            EcogridQueryParser parser = new EcogridQueryParser(request
818
                    .getReader());
819
            parser.parseXML();
820
            QueryType queryType = parser.getEcogridQuery();
821
            EcogridJavaToMetacatJavaQueryTransformer queryTransformer = 
822
                new EcogridJavaToMetacatJavaQueryTransformer();
823
            QuerySpecification metacatQuery = queryTransformer
824
                    .transform(queryType);
825

    
826
            DBQuery metacat = new DBQuery();
827

    
828
            boolean useXMLIndex = (new Boolean(PropertyService
829
                    .getProperty("database.usexmlindex"))).booleanValue();
830
            String xmlquery = "query"; // we don't care the query in resultset,
831
            // the query can be anything
832
            PrintWriter out = null; // we don't want metacat result, so set out null
833

    
834
            // parameter: queryspecification, user, group, usingIndexOrNot
835
            StringBuffer result = metacat.createResultDocument(xmlquery,
836
                    metacatQuery, out, username, groupNames, useXMLIndex);
837

    
838
            // create result set transfer       
839
            String saxparser = PropertyService.getProperty("xml.saxparser");
840
            MetacatResultsetParser metacatResultsetParser = new MetacatResultsetParser(
841
                    new StringReader(result.toString()), saxparser, queryType
842
                            .getNamespace().get_value());
843
            ResultsetType records = metacatResultsetParser.getEcogridResult();
844

    
845
            System.out
846
                    .println(EcogridResultsetTransformer.toXMLString(records));
847
            response.setContentType("text/xml");
848
            out = response.getWriter();
849
            out.print(EcogridResultsetTransformer.toXMLString(records));
850

    
851
        } catch (Exception e) {
852
            e.printStackTrace();
853
        }*/
854
        response.setContentType("text/xml");
855
        response.setStatus(501);
856
        PrintWriter out = response.getWriter();
857
        out.print("<error>Query operation not yet supported by Metacat.</error>");
858
        out.close();
859
    }
860

    
861
}
(1-1/11)