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 15:54:03 -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.util.Date;
33
import java.util.Hashtable;
34
import java.util.Map;
35
import java.util.Timer;
36

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

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

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

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

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

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

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

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

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

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

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

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

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

    
433
    /**
434
     * Implements REST version of DataONE CRUD API --> get
435
     * @param guid ID of data object to be read
436
     */
437
    protected void getObject(String guid) {
438
        OutputStream out = null;
439
        try {
440
            out = response.getOutputStream();
441
            response.setStatus(200);
442
            
443
            if(guid != null)
444
            { //get a specific document                
445
                Identifier id = new Identifier();
446
                id.setValue(guid);
447
                try
448
                {
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
                    IOUtils.copyLarge(data, response.getOutputStream());
478
                }
479
                catch(InvalidToken it)
480
                {
481
                    response.setStatus(500);
482
                    serializeException(it, out); 
483
                }
484
                catch(ServiceFailure sf)
485
                {
486
                    response.setStatus(500);
487
                    serializeException(sf, out); 
488
                }
489
                catch(NotAuthorized na)
490
                {
491
                    response.setStatus(500);
492
                    serializeException(na, out); 
493
                }
494
                catch(NotFound nf)
495
                {
496
                    response.setStatus(500);
497
                    serializeException(nf, out); 
498
                }
499
                catch(NotImplemented ni)
500
                {
501
                    response.setStatus(500);
502
                    serializeException(ni, out); 
503
                }
504
                catch(Exception e)
505
                {
506
                    response.setStatus(500);
507
                    logMetacat.error("Error with Crud.get().  " +
508
                            "If this is an 'Exception producing data' error, " +
509
                            "go to CrudService.get() for better debugging.  " +
510
                            "Here's the error: " + e.getClass() + ": " + e.getMessage());
511
                    e.printStackTrace();
512
                    ServiceFailure sf = new ServiceFailure("1030", 
513
                            "IO Error in D1ResourceHandler.getObject: " + e.getClass() + ": " + e.getMessage());
514
                    serializeException(sf, out); 
515
                }
516
            }
517
            
518
        } catch (IOException e) {
519
            e.printStackTrace();
520
            response.setStatus(500);
521
            ServiceFailure sf = new ServiceFailure("1030", 
522
                    "IO Error in D1ResourceHandler.getObject: " + e.getMessage());
523
            serializeException(sf, out); 
524
        } catch(NumberFormatException ne) {
525
            response.setStatus(500);
526
            InvalidRequest ir = new InvalidRequest("1030", "Invalid format for parameter: " + ne.getMessage());
527
            serializeException(ir, out);
528
        } catch (Exception e) {
529
            e.printStackTrace();
530
            response.setStatus(500);
531
            ServiceFailure sf = new ServiceFailure("1030", 
532
                    "Exception " + e.getClass().getName() + " raised while handling listObjects request: " + 
533
                    e.getMessage());
534
            serializeException(sf, out);
535
        }
536
    }
537
    
538

    
539
    /**
540
     * Implements REST version of DataONE CRUD API --> getSystemMetadata
541
     * @param guid ID of data object to be read
542
     */
543
    protected void getSystemMetadataObject(String guid) {
544
        OutputStream out = null;
545
        try {
546
            response.setContentType("text/xml");
547
            response.setStatus(200);
548
            out = response.getOutputStream();
549
            Identifier id = new Identifier();
550
            id.setValue(guid);
551
            SystemMetadata sysmeta = CNodeService.getInstance().getSystemMetadata(session, id);
552
            
553
            // Serialize and write it to the output stream
554
            try {
555
                //TODO: look at the efficiency of this method.  The system metadata
556
                //is read from metacat (in CrudService) as xml, then serialized
557
                //to a SystemMetadat object, then returned here, then serizlized
558
                //back to XML to be sent to the response.
559
                serializeServiceType(SystemMetadata.class, sysmeta, out);
560
            } catch (JiBXException e) {
561
                throw new ServiceFailure("1190", "Failed to serialize SystemMetadata: " + e.getMessage());
562
            }
563
        } catch (BaseException e) {
564
            response.setStatus(500);
565
                serializeException(e, out);
566
        } catch (IOException e) {
567
            response.setStatus(500);
568
            ServiceFailure sf = new ServiceFailure("1030", 
569
                    "IO Error in D1ResourceHandler.getSystemMetadataObject: " + e.getMessage());
570
            serializeException(sf, out);
571
        } finally {
572
            IOUtils.closeQuietly(out);
573
        }
574
    }
575
    
576
    /**
577
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler > handleInsertOrUpdateAction 
578
     * 
579
     * @param guid - ID of data object to be inserted or updated.  If action is update, the pid
580
     *               is the existing pid.  If insert, the pid is the new one
581
     * @throws InvalidRequest 
582
     * @throws ServiceFailure 
583
     * @throws IdentifierNotUnique 
584
     * @throws JiBXException 
585
     * @throws NotImplemented 
586
     * @throws InvalidSystemMetadata 
587
     * @throws InsufficientResources 
588
     * @throws UnsupportedType 
589
     * @throws NotAuthorized 
590
     * @throws InvalidToken 
591
     * @throws IOException 
592
     */
593
    protected void putObject(String pid, String action) throws ServiceFailure, InvalidRequest, IdentifierNotUnique, JiBXException, InvalidToken, NotAuthorized, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, IOException {
594
        logMetacat.debug("Entering putObject: " + pid + "/" + action);
595
        
596
        // Read the incoming data from its Mime Multipart encoding
597
    	Map<String, File> files = collectMultipartFiles();
598
        InputStream object = null;
599
        InputStream sysmeta = null;
600

    
601
        File smFile = files.get("sysmeta");
602
        sysmeta = new FileInputStream(smFile);
603
        File objFile = files.get("object");
604
        object = new FileInputStream(objFile);
605
       
606
        if ( action.equals(FUNCTION_NAME_INSERT)) { //handle inserts
607

    
608
            logMetacat.debug("Commence creation...");
609
            SystemMetadata smd = (SystemMetadata) deserializeServiceType(SystemMetadata.class, sysmeta);
610

    
611
            Identifier id = new Identifier();
612
            id.setValue(pid);
613
            logMetacat.debug("creating object with pid " + id.getValue());
614
            Identifier rId = CNodeService.getInstance().create(session, id, object, smd);
615
            
616
            OutputStream out = response.getOutputStream();
617
            response.setStatus(200);
618
            response.setContentType("text/xml");
619
            
620
            serializeServiceType(Identifier.class, rId, out);
621
            
622
        } else {
623
            throw new InvalidRequest("1000", "Operation must be create.");
624
        }
625
    }
626

    
627
    /**
628
     * List the object formats registered with the system
629
     */
630
		private void listFormats() {
631
      logMetacat.debug("Entering listFormats()");
632
      // get the response output stream
633
      OutputStream out = null;
634
      
635
      try {
636
	      out = response.getOutputStream();
637
	      response.setStatus(200);
638
	      response.setContentType("text/xml");
639
	      
640
      } catch (IOException ioe) {
641
      	logMetacat.error("Could not get the output stream for writing" +
642
      	  "in D1ResourceHandler.listFormats()");
643
      
644
      }
645

    
646
      // get the object format list
647
      try {
648
	      ObjectFormatList objectFormatList = CNodeService.getInstance().listFormats();
649
	      serializeServiceType(ObjectFormatList.class, objectFormatList, out);
650
      
651
      } catch (InvalidRequest e) {
652
      	response.setStatus(200);
653
      	serializeException(e, out);
654
      	
655
      } catch (ServiceFailure e) {
656
      	response.setStatus(501);
657
      	serializeException(e, out);
658
      
659
      } catch (NotFound e) {
660
      	response.setStatus(200);
661
      	serializeException(e, out);
662
      
663
      } catch (InsufficientResources e) {
664
      	response.setStatus(200);
665
      	serializeException(e, out);
666
      
667
      } catch (NotImplemented e) {
668
      	response.setStatus(200);
669
      	serializeException(e, out);
670
      
671
      } catch (JiBXException jibxe) {
672
      	response.setStatus(501);
673
      	ServiceFailure e = 
674
      		new ServiceFailure("4841", "Unexpected exception from the service - " + 
675
        	                   jibxe.getClass() + ": " + jibxe.getMessage());
676
      	serializeException(e, out);
677
      	
678
      }
679
      
680
    }
681

    
682
		/**
683
     * Return the requested object format
684
     * 
685
     * @param fmtidStr the requested format identifier as a string
686
     */
687
    private void getFormat(String fmtidStr) {
688
      logMetacat.debug("Entering listFormats()");
689
      
690
      // get the response output stream
691
      OutputStream out = null;
692
      try {
693
	      out = response.getOutputStream();
694
	      response.setStatus(200);
695
	      response.setContentType("text/xml");
696
	      
697
      } catch (IOException ioe) {
698
      	logMetacat.error("Could not get the output stream for writing" +
699
      	  "in D1ResourceHandler.listFormats()");
700
      
701
      }
702
      
703
      ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
704
      fmtid.setValue(fmtidStr);
705
      
706
      try {
707
      	// get the specified object format
708
	      ObjectFormat objectFormat = CNodeService.getInstance().getFormat(fmtid);
709
	      serializeServiceType(ObjectFormat.class, objectFormat, out);
710

    
711
      } catch (InvalidRequest e) {
712
      	response.setStatus(200);
713
      	serializeException(e, out);
714
      
715
      } catch (ServiceFailure e) {
716
      	response.setStatus(501);
717
      	serializeException(e, out);
718
      
719
      } catch (NotFound e) {
720
      	response.setStatus(200);
721
      	serializeException(e, out);
722
      
723
      } catch (InsufficientResources e) {
724
      	response.setStatus(200);
725
      	serializeException(e, out);
726
      
727
      } catch (NotImplemented e) {
728
      	response.setStatus(200);
729
      	serializeException(e, out);
730
      
731
      } catch (JiBXException jibxe) {
732
      	ServiceFailure e = 
733
      		new ServiceFailure("4841", "Unexpected exception from the service - " + 
734
        	                   jibxe.getClass() + ": " + jibxe.getMessage());
735
      	serializeException(e, out);
736

    
737
      }
738
	    
739
    }
740
    
741
    /**
742
     * Reserve the given Identifier
743
     * @throws InvalidToken
744
     * @throws ServiceFailure
745
     * @throws NotAuthorized
746
     * @throws IdentifierNotUnique
747
     * @throws NotImplemented
748
     * @throws InvalidRequest
749
     * @throws IOException 
750
     */
751
    private void reserve() throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest, IOException {
752
    	String id = params.get("pid")[0];
753
    	String format = params.get("format")[0];
754
		String scope = params.get("scope")[0];
755
		Identifier pid = new Identifier();
756
		pid.setValue(id);
757
		Identifier retPid = CNodeService.getInstance().reserveIdentifier(session, pid, scope, format);
758
		OutputStream out = response.getOutputStream();
759
		response.setStatus(200);
760
		response.setContentType("text/xml");
761
		try {
762
			serializeServiceType(Identifier.class, retPid, out);
763
		} catch (JiBXException e) {
764
	      throw new ServiceFailure("4210", 
765
	      				"Unexpected exception from the service - " + 
766
	        	                   e.getClass() + ": " + e.getMessage());
767
		}
768
		
769
    }
770
    
771
    private void resolve(String id) throws InvalidRequest, InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, IOException {
772
		Identifier pid = new Identifier();
773
		pid.setValue(id);
774
		ObjectLocationList locationList = CNodeService.getInstance().resolve(session, pid);
775
	    OutputStream out = response.getOutputStream();
776
		response.setStatus(200);
777
		response.setContentType("text/xml");
778
		try {
779
			serializeServiceType(ObjectLocationList.class, locationList, out);
780
		} catch (JiBXException e) {
781
	      throw new ServiceFailure("4150", 
782
	      				"Unexpected exception from the service - " + 
783
	        	                   e.getClass() + ": " + e.getMessage());
784
		}
785
    }
786

    
787
    private boolean assertRelation(String id) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented {
788
		Identifier pidOfSubject = new Identifier();
789
		pidOfSubject.setValue(id);
790
		Identifier pidOfObject = new Identifier();
791
		String relationship;
792
		relationship = params.get("relationship")[0];
793
		String objPid = params.get("pidOfObject")[0];
794
		pidOfObject.setValue(objPid);
795
		boolean result = CNodeService.getInstance().assertRelation(session, pidOfSubject, relationship, pidOfObject);
796
		response.setStatus(200);
797
		response.setContentType("text/xml");
798
		return result;
799
    }
800
    
801
    private void owner(String id) throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException {
802
		Identifier pid = new Identifier();
803
		pid.setValue(id);
804
		String subjectStr = params.get("subject")[0];
805
		Subject subject = (Subject) deserializeServiceType(Subject.class, new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
806
		Identifier retPid = CNodeService.getInstance().setOwner(session, pid, subject);
807
		OutputStream out = response.getOutputStream();
808
		response.setStatus(200);
809
		response.setContentType("text/xml");
810
		try {
811
			serializeServiceType(Identifier.class, retPid, out);
812
		} catch (JiBXException e) {
813
	      throw new ServiceFailure("4490", 
814
	      				"Unexpected exception from the service - " + 
815
	        	                   e.getClass() + ": " + e.getMessage());
816
		}
817
		
818
    }
819
    
820
    private boolean isAuthorized(String id) throws ServiceFailure, InvalidToken, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
821
		Identifier pid = new Identifier();
822
		pid.setValue(id);
823
		String permission = params.get("permission")[0];
824
		boolean result = CNodeService.getInstance().isAuthorized(session, pid, Permission.valueOf(permission));
825
		response.setStatus(200);
826
		response.setContentType("text/xml");
827
		return result;
828
    }
829
    
830
    /**
831
     * Register System Metadata without data or metadata object
832
     * @param pid identifier for System Metadata entry
833
     * @throws JiBXException 
834
     * @throws FileUploadException 
835
     * @throws IOException 
836
     * @throws InvalidRequest 
837
     * @throws ServiceFailure 
838
     * @throws InvalidSystemMetadata 
839
     * @throws NotAuthorized 
840
     * @throws NotImplemented 
841
     */
842
    protected boolean registerSystemMetadata(String pid) throws ServiceFailure, InvalidRequest, IOException, FileUploadException, JiBXException, NotImplemented, NotAuthorized, InvalidSystemMetadata {
843
		logMetacat.debug("Entering registerSystemMetadata: " + pid);
844

    
845
		// get the system metadata from the request
846
		SystemMetadata systemMetadata = collectSystemMetadata();
847

    
848
		Identifier guid = new Identifier();
849
		guid.setValue(pid);
850
		logMetacat.debug("registering system metadata with pid " + guid.getValue());
851
		boolean result = CNodeService.getInstance().registerSystemMetadata(session, guid, systemMetadata);
852
		
853
		response.setStatus(200);
854
		response.setContentType("text/xml");
855
		return result;
856
			
857
	}
858
    
859
    /**
860
     * set the access perms on a document
861
     * @throws Exception
862
     */
863
    protected void setaccess() throws Exception
864
    {
865
        try
866
        {
867
            String guid = params.get("guid")[0];
868
            Identifier id = new Identifier();
869
            id.setValue(guid);
870
            String accesspolicy = params.get("accesspolicy")[0];
871
            AccessPolicy accessPolicy = (AccessPolicy) deserializeServiceType(AccessPolicy.class, new ByteArrayInputStream(accesspolicy.getBytes("UTF-8")));
872
            CNodeService.getInstance().setAccessPolicy(session, id, accessPolicy);
873
        }
874
        catch(Exception e)
875
        {
876
            response.setStatus(500);
877
            printError("Error setting access in D1ResourceHandler: " + e.getClass() + ": " + e.getMessage(), response);
878
            throw e;
879
        }
880
    }
881
    
882
    /**
883
     * Earthgrid API > Query Service > Query Function : translates ecogrid query document to metacat query 
884
     * then calls DBQuery > createResultDocument function and then again translate resultset to ecogrid resultset
885
     * 
886
     * NOTE:
887
     *      This is the only method that uses EcoGrid classes for its implementation.  
888
     *      It does so because it takes an EcoGrid Query as input, and outputs an
889
     *      EcoGrid ResultSet document.  These documents are parsed by the auto-generated
890
     *      EcoGrid classes from axis, and so we link to them here rather than re-inventing them.
891
     *      This creates a circular dependency, because the Metacat classes are needed
892
     *      to build the EcoGrid implementation, and the EcoGrid jars are needed to build this query()
893
     *      method.  This circularity could be resolved by moving the EcoGrid classes
894
     *      to Metacat directly.  As we transition away from EcoGrid SOAP methods in
895
     *      favor of these REST interfaces, this circular dependency can be eliminated.
896
     *        
897
     * @throws Exception
898
     */
899
    private void query() throws Exception {
900
        /*  This block commented out because of the EcoGrid circular dependency.
901
         *  For now, query will not be supported until the circularity can be
902
         *  resolved, probably by moving the ecogrid query syntax transformers
903
         *  directly into the Metacat codebase.  MBJ 2010-02-03
904
         
905
        try {
906
            EcogridQueryParser parser = new EcogridQueryParser(request
907
                    .getReader());
908
            parser.parseXML();
909
            QueryType queryType = parser.getEcogridQuery();
910
            EcogridJavaToMetacatJavaQueryTransformer queryTransformer = 
911
                new EcogridJavaToMetacatJavaQueryTransformer();
912
            QuerySpecification metacatQuery = queryTransformer
913
                    .transform(queryType);
914

    
915
            DBQuery metacat = new DBQuery();
916

    
917
            boolean useXMLIndex = (new Boolean(PropertyService
918
                    .getProperty("database.usexmlindex"))).booleanValue();
919
            String xmlquery = "query"; // we don't care the query in resultset,
920
            // the query can be anything
921
            PrintWriter out = null; // we don't want metacat result, so set out null
922

    
923
            // parameter: queryspecification, user, group, usingIndexOrNot
924
            StringBuffer result = metacat.createResultDocument(xmlquery,
925
                    metacatQuery, out, username, groupNames, useXMLIndex);
926

    
927
            // create result set transfer       
928
            String saxparser = PropertyService.getProperty("xml.saxparser");
929
            MetacatResultsetParser metacatResultsetParser = new MetacatResultsetParser(
930
                    new StringReader(result.toString()), saxparser, queryType
931
                            .getNamespace().get_value());
932
            ResultsetType records = metacatResultsetParser.getEcogridResult();
933

    
934
            System.out
935
                    .println(EcogridResultsetTransformer.toXMLString(records));
936
            response.setContentType("text/xml");
937
            out = response.getWriter();
938
            out.print(EcogridResultsetTransformer.toXMLString(records));
939

    
940
        } catch (Exception e) {
941
            e.printStackTrace();
942
        }*/
943
        response.setContentType("text/xml");
944
        response.setStatus(501);
945
        PrintWriter out = response.getWriter();
946
        out.print("<error>Query operation not yet supported by Metacat.</error>");
947
        out.close();
948
    }
949

    
950
}
(1-1/11)