Project

General

Profile

1 6253 leinfelder
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2011 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author$'
7
 *     '$Date$'
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.util.Date;
32
import java.util.Map;
33
34
import javax.servlet.ServletContext;
35
import javax.servlet.http.HttpServletRequest;
36
import javax.servlet.http.HttpServletResponse;
37
38 6269 leinfelder
import org.apache.commons.fileupload.FileUploadException;
39 6253 leinfelder
import org.apache.commons.io.IOUtils;
40
import org.apache.log4j.Logger;
41
import org.dataone.client.ObjectFormatCache;
42
import org.dataone.service.exceptions.BaseException;
43
import org.dataone.service.exceptions.IdentifierNotUnique;
44
import org.dataone.service.exceptions.InsufficientResources;
45
import org.dataone.service.exceptions.InvalidRequest;
46
import org.dataone.service.exceptions.InvalidSystemMetadata;
47
import org.dataone.service.exceptions.InvalidToken;
48
import org.dataone.service.exceptions.NotAuthorized;
49
import org.dataone.service.exceptions.NotFound;
50
import org.dataone.service.exceptions.NotImplemented;
51
import org.dataone.service.exceptions.ServiceFailure;
52
import org.dataone.service.exceptions.UnsupportedType;
53 6366 leinfelder
import org.dataone.service.types.v1.AccessPolicy;
54
import org.dataone.service.types.v1.Checksum;
55
import org.dataone.service.types.v1.Event;
56
import org.dataone.service.types.v1.Identifier;
57
import org.dataone.service.types.v1.Log;
58
import org.dataone.service.types.v1.ObjectFormat;
59
import org.dataone.service.types.v1.ObjectFormatIdentifier;
60
import org.dataone.service.types.v1.ObjectFormatList;
61
import org.dataone.service.types.v1.ObjectLocationList;
62
import org.dataone.service.types.v1.Permission;
63
import org.dataone.service.types.v1.Subject;
64
import org.dataone.service.types.v1.SystemMetadata;
65 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
66 6253 leinfelder
import org.jibx.runtime.JiBXException;
67
68
import edu.ucsb.nceas.metacat.dataone.CNodeService;
69
70
/**
71
 * CN REST service implementation handler
72
 *
73
 * ******************
74
 	CNCore -- DONE
75
		create() - POST /d1/cn/object/PID
76
		listFormats() - GET /d1/cn/formats
77
		getFormat() - GET /d1/cn/formats/FMTID
78
		getLogRecords - GET /d1/cn/log
79
		reserveIdentifier() - POST /d1/cn/reserve
80
		listNodes() - Not implemented
81
		registerSystemMetadata() - POST /d1/meta/PID
82
83
	CNRead -- DONE
84
		get() - GET /d1/cn/object/PID
85
		getSystemMetadata() - GET /d1/cn/meta/PID
86
		resolve() - GET /d1/cn/resolve/PID
87
		assertRelation() - GET /d1/cn/assertRelation/PID
88
		getChecksum() - GET /d1/cn/checksum
89
		search() - Not implemented in Metacat
90
91
	CNAuthorization
92
		setOwner() - PUT /d1/cn/owner/PID
93
		isAuthorized() - GET /d1/cn/isAuthorized/PID
94
		setAccessPolicy() - POST /d1/cn/accessRules
95
96
	CNIdentity - not implemented at all on Metacat
97
98
	CNReplication
99
		setReplicationStatus() - Not exposed
100
		updateReplicationMetadata() - New method?
101
		setReplicationPolicy() - Not exposed
102
103
	CNRegister -- not implemented at all in Metacat
104
 * ******************
105
 * @author leinfelder
106
 *
107
 */
108 6267 leinfelder
public class CNResourceHandler extends D1ResourceHandler {
109 6253 leinfelder
110
	/** CN-specific operations **/
111
    protected static final String RESOURCE_RESERVE = "reserve";
112 6271 leinfelder
    protected static final String RESOURCE_FORMATS = "formats";
113 6253 leinfelder
    protected static final String RESOURCE_RESOLVE = "resolve";
114
    protected static final String RESOURCE_ASSERT_RELATION = "assertRelation";
115
    protected static final String RESOURCE_OWNER = "owner";
116
    protected static final String RESOURCE_NOTIFY = "notify";
117
    protected static final String RESOURCE_META_REPLICATION = "meta/replication";
118
    protected static final String RESOURCE_META_POLICY = "meta/policy";
119
120
    public CNResourceHandler(ServletContext servletContext,
121
			HttpServletRequest request, HttpServletResponse response) {
122
		super(servletContext, request, response);
123
        logMetacat = Logger.getLogger(CNResourceHandler.class);
124
	}
125
126
	/**
127 6271 leinfelder
     * This function is called from REST API servlet and handles each request to the servlet
128 6253 leinfelder
     *
129
     * @param httpVerb (GET, POST, PUT or DELETE)
130
     */
131 6271 leinfelder
    @Override
132 6253 leinfelder
    public void handle(byte httpVerb) {
133 6271 leinfelder
    	// prepare the handler
134
    	super.handle(httpVerb);
135
136 6253 leinfelder
        try {
137 6282 leinfelder
138
        	// get the resource
139
            String resource = request.getPathInfo();
140
            resource = resource.substring(resource.indexOf("/") + 1);
141 6253 leinfelder
142 6396 leinfelder
            // for the rest of the resouce
143 6282 leinfelder
            String extra = null;
144
145 6253 leinfelder
            logMetacat.debug("handling verb " + httpVerb + " request with resource '" + resource + "'");
146
            boolean status = false;
147 6271 leinfelder
148 6253 leinfelder
            if (resource != null) {
149
150 6282 leinfelder
                if (resource.startsWith(RESOURCE_ACCESS_RULES) && httpVerb == PUT) {
151 6253 leinfelder
                    logMetacat.debug("Setting access policy");
152 6270 leinfelder
                    setAccess();
153 6253 leinfelder
                    status = true;
154
                    logMetacat.debug("done setting access");
155
156 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_META)) {
157 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_META);
158 6282 leinfelder
159 6396 leinfelder
                    // after the command
160
                    extra = parseTrailing(resource, RESOURCE_META);
161
162 6253 leinfelder
                    // get
163
                    if (httpVerb == GET) {
164 6282 leinfelder
                        getSystemMetadataObject(extra);
165 6253 leinfelder
                        status = true;
166
                    }
167
                    // post to register system metadata
168
                    if (httpVerb == POST) {
169 6282 leinfelder
                    	registerSystemMetadata(extra);
170 6253 leinfelder
                    	status = true;
171
                    }
172
173 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESERVE)) {
174 6253 leinfelder
                    // reserve the ID (in params)
175
                    if (httpVerb == POST) {
176
                    	reserve();
177
                    	status = true;
178
                    }
179 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_ASSERT_RELATION)) {
180
181 6396 leinfelder
                	// after the command
182
                    extra = parseTrailing(resource, RESOURCE_ASSERT_RELATION);
183
184 6253 leinfelder
                    // reserve the ID (in params)
185
                    if (httpVerb == GET) {
186 6282 leinfelder
                    	assertRelation(extra);
187 6253 leinfelder
                    	status = true;
188
                    }
189 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESOLVE)) {
190
191 6396 leinfelder
                	// after the command
192
                    extra = parseTrailing(resource, RESOURCE_RESOLVE);
193
194 6253 leinfelder
                    // resolve the object location
195
                    if (httpVerb == GET) {
196 6282 leinfelder
                    	resolve(extra);
197 6253 leinfelder
                    	status = true;
198
                    }
199 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OWNER)) {
200
201 6396 leinfelder
                	// after the command
202
                    extra = parseTrailing(resource, RESOURCE_OWNER);
203
204 6253 leinfelder
                    // set the owner
205
                    if (httpVerb == PUT) {
206 6282 leinfelder
                    	owner(extra);
207 6253 leinfelder
                    	status = true;
208
                    }
209 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_IS_AUTHORIZED)) {
210
211 6396 leinfelder
                	// after the command
212
                    extra = parseTrailing(resource, RESOURCE_IS_AUTHORIZED);
213
214 6253 leinfelder
                    // authorized?
215
                    if (httpVerb == GET) {
216 6282 leinfelder
                    	isAuthorized(extra);
217 6253 leinfelder
                    	status = true;
218
                    }
219 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OBJECTS)) {
220 6253 leinfelder
                    logMetacat.debug("Using resource 'object'");
221
                    logMetacat.debug("D1 Rest: Starting resource processing...");
222
223 6396 leinfelder
                    // after the command
224
                    extra = parseTrailing(resource, RESOURCE_OBJECTS);
225
226 6282 leinfelder
                    logMetacat.debug("objectId: " + extra);
227 6253 leinfelder
                    logMetacat.debug("verb:" + httpVerb);
228
229
                    if (httpVerb == GET) {
230 6282 leinfelder
                    	if (extra != null) {
231
                    		getObject(extra);
232
                    	} else {
233
                    		query();
234
                    	}
235 6253 leinfelder
                        status = true;
236
                    } else if (httpVerb == POST) {
237 6282 leinfelder
                        putObject(extra, FUNCTION_NAME_INSERT);
238 6253 leinfelder
                        status = true;
239
                    }
240
241 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_FORMATS)) {
242 6253 leinfelder
                  logMetacat.debug("Using resource: " + RESOURCE_FORMATS);
243
244 6396 leinfelder
                  // after the command
245
                  extra = parseTrailing(resource, RESOURCE_FORMATS);
246 6253 leinfelder
247
                  // handle each verb
248
                  if (httpVerb == GET) {
249 6282 leinfelder
                  	if (extra == null) {
250 6253 leinfelder
                  		// list the formats collection
251
                  		listFormats();
252
                  	} else {
253
                  		// get the specified format
254 6282 leinfelder
                  		getFormat(extra);
255 6253 leinfelder
                  	}
256
                  	status = true;
257
                  }
258
259 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_LOG)) {
260 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_LOG);
261
                    //handle log events
262
                    if (httpVerb == GET) {
263
                        getLog();
264
                        status = true;
265
                    }
266
267 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_CHECKSUM)) {
268 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_CHECKSUM);
269 6396 leinfelder
270
                    // after the command
271
                    extra = parseTrailing(resource, RESOURCE_CHECKSUM);
272
273 6253 leinfelder
                    //handle checksum requests
274
                    if (httpVerb == GET) {
275
276 6282 leinfelder
                        checksum(extra);
277 6253 leinfelder
                        status = true;
278
                    }
279
                }
280
281
                if (!status) {
282 6271 leinfelder
                	throw new ServiceFailure("0000", "Unknown error, status = " + status);
283 6253 leinfelder
                }
284
            } else {
285 6270 leinfelder
            	throw new InvalidRequest("0000", "No resource matched for " + resource);
286 6253 leinfelder
            }
287
        } catch (BaseException be) {
288 6270 leinfelder
        	// report Exceptions as clearly and generically as possible
289 6253 leinfelder
        	OutputStream out = null;
290
			try {
291
				out = response.getOutputStream();
292 6270 leinfelder
			} catch (IOException ioe) {
293
				logMetacat.error("Could not get output stream from response", ioe);
294 6253 leinfelder
			}
295
            serializeException(be, out);
296
        } catch (Exception e) {
297 6270 leinfelder
            // report Exceptions as clearly and generically as possible
298 6253 leinfelder
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
299 6270 leinfelder
        	OutputStream out = null;
300
			try {
301
				out = response.getOutputStream();
302
			} catch (IOException ioe) {
303
				logMetacat.error("Could not get output stream from response", ioe);
304
			}
305
			ServiceFailure se = new ServiceFailure("0000", e.getMessage());
306
            serializeException(se, out);
307 6253 leinfelder
        }
308
    }
309
310 6396 leinfelder
    private String parseTrailing(String resource, String token) {
311
    	// get the rest
312
        String extra = null;
313
        if (resource.indexOf(token) != -1) {
314
        	// what comes after the token?
315
            extra = resource.substring(resource.indexOf(token) + token.length());
316
            // remove the slash
317
            if (extra.startsWith("/")) {
318
            	extra = extra.substring(1);
319
            }
320
            // is there anything left?
321
            if (extra.length() == 0) {
322
            	extra = null;
323
            }
324
        }
325
        return extra;
326
    }
327
328 6270 leinfelder
    /**
329
     * Get the checksum for the given guid
330
     *
331
     * @param guid
332
     * @throws NotImplemented
333
     * @throws InvalidRequest
334
     * @throws NotFound
335
     * @throws NotAuthorized
336
     * @throws ServiceFailure
337
     * @throws InvalidToken
338
     * @throws IOException
339
     * @throws JiBXException
340
     */
341
    private void checksum(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, JiBXException, IOException {
342
    	Identifier guidid = new Identifier();
343
        guidid.setValue(guid);
344
        logMetacat.debug("getting checksum for object " + guid);
345
        Checksum c = CNodeService.getInstance().getChecksum(session, guidid);
346
        logMetacat.debug("got checksum " + c.getValue());
347
        response.setStatus(200);
348
        logMetacat.debug("serializing response");
349 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(c, response.getOutputStream());
350 6270 leinfelder
        logMetacat.debug("done serializing response.");
351
352
    }
353
354 6253 leinfelder
	/**
355 6362 leinfelder
     * get the logs based on passed params.  Available
356 6253 leinfelder
     * params are token, fromDate, toDate, event.  See
357
     * http://mule1.dataone.org/ArchitectureDocs/mn_api_crud.html#MN_crud.getLogRecords
358
     * for more info
359 6270 leinfelder
	 * @throws NotImplemented
360
	 * @throws InvalidRequest
361
	 * @throws NotAuthorized
362
	 * @throws ServiceFailure
363
	 * @throws InvalidToken
364
	 * @throws IOException
365
	 * @throws JiBXException
366 6253 leinfelder
     */
367 6270 leinfelder
    private void getLog() throws InvalidToken, ServiceFailure, NotAuthorized, InvalidRequest, NotImplemented, IOException, JiBXException
368 6253 leinfelder
    {
369 6270 leinfelder
370
        Date fromDate = null;
371
        Date toDate = null;
372
        Event event = null;
373
        Integer start = null;
374
        Integer count = null;
375
376
        try {
377
        	String fromDateS = params.get("fromDate")[0];
378 6272 leinfelder
            logMetacat.debug("param fromDateS: " + fromDateS);
379 6270 leinfelder
            fromDate = parseDateAndConvertToGMT(fromDateS);
380
        } catch (Exception e) {
381
        	logMetacat.warn("Could not parse fromDate: " + e.getMessage());
382 6253 leinfelder
        }
383 6270 leinfelder
        try {
384
        	String toDateS = params.get("toDate")[0];
385 6272 leinfelder
            logMetacat.debug("param toDateS: " + toDateS);
386 6270 leinfelder
            toDate = parseDateAndConvertToGMT(toDateS);
387
        } catch (Exception e) {
388
        	logMetacat.warn("Could not parse toDate: " + e.getMessage());
389
		}
390
        try {
391
        	String eventS = params.get("event")[0];
392
            event = Event.convert(eventS);
393
        } catch (Exception e) {
394
        	logMetacat.warn("Could not parse event: " + e.getMessage());
395
		}
396 6272 leinfelder
        logMetacat.debug("fromDate: " + fromDate + " toDate: " + toDate);
397 6270 leinfelder
398
        try {
399
        	start =  Integer.parseInt(params.get("start")[0]);
400
        } catch (Exception e) {
401
			logMetacat.warn("Could not parse start: " + e.getMessage());
402
		}
403
        try {
404
        	count =  Integer.parseInt(params.get("count")[0]);
405
        } catch (Exception e) {
406
			logMetacat.warn("Could not parse count: " + e.getMessage());
407
		}
408
409 6272 leinfelder
        logMetacat.debug("calling getLogRecords");
410 6270 leinfelder
        Log log = CNodeService.getInstance().getLogRecords(session, fromDate, toDate, event, start, count);
411
412
        OutputStream out = response.getOutputStream();
413
        response.setStatus(200);
414
        response.setContentType("text/xml");
415
416 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(log, out);
417 6270 leinfelder
418 6253 leinfelder
    }
419
420
    /**
421
     * Implements REST version of DataONE CRUD API --> get
422
     * @param guid ID of data object to be read
423 6270 leinfelder
     * @throws NotImplemented
424
     * @throws InvalidRequest
425
     * @throws NotFound
426
     * @throws NotAuthorized
427
     * @throws ServiceFailure
428
     * @throws InvalidToken
429
     * @throws IOException
430 6253 leinfelder
     */
431 6270 leinfelder
    protected void getObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException {
432
433 6280 leinfelder
        Identifier id = new Identifier();
434
        id.setValue(guid);
435
436
        SystemMetadata sm = CNodeService.getInstance().getSystemMetadata(session, id);
437 6270 leinfelder
438 6280 leinfelder
        //set the content type
439 6384 cjones
        if(sm.getFmtid().getValue().trim().equals(
440 6280 leinfelder
        		ObjectFormatCache.getInstance().getFormat("text/csv").getFmtid().getValue()))
441
        {
442
            response.setContentType("text/csv");
443
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".csv");
444 6253 leinfelder
        }
445 6384 cjones
        else if(sm.getFmtid().getValue().trim().equals(
446 6280 leinfelder
        		ObjectFormatCache.getInstance().getFormat("text/plain").getFmtid().getValue()))
447
        {
448
            response.setContentType("text/plain");
449
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".txt");
450
        }
451 6384 cjones
        else if(sm.getFmtid().getValue().trim().equals(
452 6280 leinfelder
        		ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFmtid().getValue()))
453
        {
454
            response.setContentType("application/octet-stream");
455
        }
456
        else
457
        {
458
            response.setContentType("text/xml");
459
            response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".xml");
460
        }
461
462
        InputStream data = CNodeService.getInstance().get(session, id);
463
464
        OutputStream out = response.getOutputStream();
465
        response.setStatus(200);
466
        IOUtils.copyLarge(data, out);
467 6270 leinfelder
468 6253 leinfelder
    }
469
470
471
    /**
472
     * Implements REST version of DataONE CRUD API --> getSystemMetadata
473
     * @param guid ID of data object to be read
474 6270 leinfelder
     * @throws NotImplemented
475
     * @throws InvalidRequest
476
     * @throws NotFound
477
     * @throws NotAuthorized
478
     * @throws ServiceFailure
479
     * @throws InvalidToken
480
     * @throws IOException
481
     * @throws JiBXException
482 6253 leinfelder
     */
483 6270 leinfelder
    protected void getSystemMetadataObject(String guid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented, IOException, JiBXException {
484
485
        Identifier id = new Identifier();
486
        id.setValue(guid);
487
        SystemMetadata sysmeta = CNodeService.getInstance().getSystemMetadata(session, id);
488
489
        response.setContentType("text/xml");
490
        response.setStatus(200);
491
        OutputStream out = response.getOutputStream();
492
493
        // Serialize and write it to the output stream
494 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(sysmeta, out);
495 6270 leinfelder
   }
496 6253 leinfelder
497
    /**
498
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler > handleInsertOrUpdateAction
499
     *
500
     * @param guid - ID of data object to be inserted or updated.  If action is update, the pid
501
     *               is the existing pid.  If insert, the pid is the new one
502 6269 leinfelder
     * @throws InvalidRequest
503
     * @throws ServiceFailure
504
     * @throws IdentifierNotUnique
505
     * @throws JiBXException
506
     * @throws NotImplemented
507
     * @throws InvalidSystemMetadata
508
     * @throws InsufficientResources
509
     * @throws UnsupportedType
510
     * @throws NotAuthorized
511
     * @throws InvalidToken
512
     * @throws IOException
513 6367 leinfelder
     * @throws IllegalAccessException
514
     * @throws InstantiationException
515 6253 leinfelder
     */
516 6367 leinfelder
    protected void putObject(String pid, String action) throws ServiceFailure, InvalidRequest, IdentifierNotUnique, JiBXException, InvalidToken, NotAuthorized, UnsupportedType, InsufficientResources, InvalidSystemMetadata, NotImplemented, IOException, InstantiationException, IllegalAccessException {
517 6253 leinfelder
        logMetacat.debug("Entering putObject: " + pid + "/" + action);
518 6269 leinfelder
519
        // Read the incoming data from its Mime Multipart encoding
520
    	Map<String, File> files = collectMultipartFiles();
521
        InputStream object = null;
522
        InputStream sysmeta = null;
523 6253 leinfelder
524 6269 leinfelder
        File smFile = files.get("sysmeta");
525
        sysmeta = new FileInputStream(smFile);
526
        File objFile = files.get("object");
527
        object = new FileInputStream(objFile);
528
529 6270 leinfelder
        if (action.equals(FUNCTION_NAME_INSERT)) { //handle inserts
530 6253 leinfelder
531 6269 leinfelder
            logMetacat.debug("Commence creation...");
532 6367 leinfelder
            SystemMetadata smd = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class, sysmeta);
533 6253 leinfelder
534 6269 leinfelder
            Identifier id = new Identifier();
535
            id.setValue(pid);
536
            logMetacat.debug("creating object with pid " + id.getValue());
537
            Identifier rId = CNodeService.getInstance().create(session, id, object, smd);
538 6253 leinfelder
539 6269 leinfelder
            OutputStream out = response.getOutputStream();
540
            response.setStatus(200);
541
            response.setContentType("text/xml");
542 6253 leinfelder
543 6367 leinfelder
            TypeMarshaller.marshalTypeToOutputStream(rId, out);
544 6269 leinfelder
545
        } else {
546
            throw new InvalidRequest("1000", "Operation must be create.");
547 6253 leinfelder
        }
548
    }
549
550
    /**
551
     * List the object formats registered with the system
552 6270 leinfelder
     * @throws NotImplemented
553
     * @throws InsufficientResources
554
     * @throws NotFound
555
     * @throws ServiceFailure
556
     * @throws InvalidRequest
557
     * @throws IOException
558
     * @throws JiBXException
559 6253 leinfelder
     */
560 6270 leinfelder
	private void listFormats() throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
561 6253 leinfelder
      logMetacat.debug("Entering listFormats()");
562 6270 leinfelder
563
      ObjectFormatList objectFormatList = CNodeService.getInstance().listFormats();
564 6253 leinfelder
      // get the response output stream
565 6270 leinfelder
      OutputStream out = response.getOutputStream();
566
      response.setStatus(200);
567
      response.setContentType("text/xml");
568 6253 leinfelder
569 6367 leinfelder
      TypeMarshaller.marshalTypeToOutputStream(objectFormatList, out);
570 6270 leinfelder
571 6253 leinfelder
    }
572
573
		/**
574
     * Return the requested object format
575
     *
576
     * @param fmtidStr the requested format identifier as a string
577 6270 leinfelder
		 * @throws NotImplemented
578
		 * @throws InsufficientResources
579
		 * @throws NotFound
580
		 * @throws ServiceFailure
581
		 * @throws InvalidRequest
582
		 * @throws IOException
583
		 * @throws JiBXException
584 6253 leinfelder
     */
585 6270 leinfelder
    private void getFormat(String fmtidStr) throws InvalidRequest, ServiceFailure, NotFound, InsufficientResources, NotImplemented, IOException, JiBXException {
586 6253 leinfelder
      logMetacat.debug("Entering listFormats()");
587
588
      ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
589
      fmtid.setValue(fmtidStr);
590
591 6270 leinfelder
	  // get the specified object format
592
      ObjectFormat objectFormat = CNodeService.getInstance().getFormat(fmtid);
593 6253 leinfelder
594 6270 leinfelder
      OutputStream out = response.getOutputStream();
595
      response.setStatus(200);
596
      response.setContentType("text/xml");
597 6253 leinfelder
598 6367 leinfelder
      TypeMarshaller.marshalTypeToOutputStream(objectFormat, out);
599 6253 leinfelder
600
    }
601
602
    /**
603
     * Reserve the given Identifier
604
     * @throws InvalidToken
605
     * @throws ServiceFailure
606
     * @throws NotAuthorized
607
     * @throws IdentifierNotUnique
608
     * @throws NotImplemented
609
     * @throws InvalidRequest
610
     * @throws IOException
611 6270 leinfelder
     * @throws JiBXException
612 6253 leinfelder
     */
613 6270 leinfelder
    private void reserve() throws InvalidToken, ServiceFailure, NotAuthorized, IdentifierNotUnique, NotImplemented, InvalidRequest, IOException, JiBXException {
614 6279 leinfelder
		Identifier pid = null;
615
		String scope = null;
616
    	String format = null;
617
    	// gather the params
618
		try {
619
	    	String id = params.get("pid")[0];
620
			pid = new Identifier();
621
			pid.setValue(id);
622
		} catch (Exception e) {
623
			logMetacat.warn("pid not specified");
624
		}
625
		try {
626
			scope = params.get("scope")[0];
627
		} catch (Exception e) {
628
			logMetacat.warn("pid not specified");
629
		}
630
		try {
631
			format = params.get("format")[0];
632
		} catch (Exception e) {
633
			logMetacat.warn("pid not specified");
634
		}
635
		// call the implementation
636 6378 leinfelder
		boolean result = CNodeService.getInstance().reserveIdentifier(session, pid);
637 6253 leinfelder
		OutputStream out = response.getOutputStream();
638
		response.setStatus(200);
639
		response.setContentType("text/xml");
640 6378 leinfelder
		// nothing to send back
641 6253 leinfelder
    }
642
643 6270 leinfelder
    /**
644
     *
645
     * @param id
646
     * @throws InvalidRequest
647
     * @throws InvalidToken
648
     * @throws ServiceFailure
649
     * @throws NotAuthorized
650
     * @throws NotFound
651
     * @throws NotImplemented
652
     * @throws IOException
653
     * @throws JiBXException
654
     */
655
    private void resolve(String id) throws InvalidRequest, InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, IOException, JiBXException {
656 6253 leinfelder
		Identifier pid = new Identifier();
657
		pid.setValue(id);
658
		ObjectLocationList locationList = CNodeService.getInstance().resolve(session, pid);
659
	    OutputStream out = response.getOutputStream();
660
		response.setStatus(200);
661
		response.setContentType("text/xml");
662 6367 leinfelder
		TypeMarshaller.marshalTypeToOutputStream(locationList, out);
663 6270 leinfelder
664 6253 leinfelder
    }
665
666 6270 leinfelder
    /**
667
     * Assert that a relationship exists between two resources
668
     * @param id
669
     * @return
670
     * @throws InvalidToken
671
     * @throws ServiceFailure
672
     * @throws NotAuthorized
673
     * @throws NotFound
674
     * @throws InvalidRequest
675
     * @throws NotImplemented
676
     */
677 6268 leinfelder
    private boolean assertRelation(String id) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, InvalidRequest, NotImplemented {
678 6253 leinfelder
		Identifier pidOfSubject = new Identifier();
679
		pidOfSubject.setValue(id);
680 6270 leinfelder
		String relationship = null;
681
		try {
682
			relationship = params.get("relationship")[0];
683
		} catch (Exception e) {
684
			logMetacat.warn("relationship not specified");
685
		}
686 6253 leinfelder
		Identifier pidOfObject = new Identifier();
687 6270 leinfelder
		try {
688
			String objPid = params.get("pidOfObject")[0];
689
			pidOfObject.setValue(objPid);
690
		} catch (Exception e) {
691
			logMetacat.warn("pidOfObject not specified");
692
		}
693 6253 leinfelder
		boolean result = CNodeService.getInstance().assertRelation(session, pidOfSubject, relationship, pidOfObject);
694
		response.setStatus(200);
695
		response.setContentType("text/xml");
696
		return result;
697
    }
698
699 6270 leinfelder
    /**
700
     * Set the owner of a resource
701
     * @param id
702
     * @throws JiBXException
703
     * @throws InvalidToken
704
     * @throws ServiceFailure
705
     * @throws NotFound
706
     * @throws NotAuthorized
707
     * @throws NotImplemented
708
     * @throws InvalidRequest
709
     * @throws IOException
710 6367 leinfelder
     * @throws IllegalAccessException
711
     * @throws InstantiationException
712 6270 leinfelder
     */
713 6367 leinfelder
    private void owner(String id) throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException, InstantiationException, IllegalAccessException {
714 6253 leinfelder
		Identifier pid = new Identifier();
715
		pid.setValue(id);
716
		String subjectStr = params.get("subject")[0];
717 6367 leinfelder
		Subject subject = TypeMarshaller.unmarshalTypeFromStream(Subject.class, new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
718 6253 leinfelder
		Identifier retPid = CNodeService.getInstance().setOwner(session, pid, subject);
719
		OutputStream out = response.getOutputStream();
720
		response.setStatus(200);
721
		response.setContentType("text/xml");
722 6367 leinfelder
		TypeMarshaller.marshalTypeToOutputStream(retPid, out);
723 6253 leinfelder
    }
724
725 6270 leinfelder
    /**
726
     * Processes the authorization check for given id
727
     * @param id
728
     * @return
729
     * @throws ServiceFailure
730
     * @throws InvalidToken
731
     * @throws NotFound
732
     * @throws NotAuthorized
733
     * @throws NotImplemented
734
     * @throws InvalidRequest
735
     */
736 6253 leinfelder
    private boolean isAuthorized(String id) throws ServiceFailure, InvalidToken, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
737
		Identifier pid = new Identifier();
738
		pid.setValue(id);
739
		String permission = params.get("permission")[0];
740 6373 leinfelder
		boolean result = CNodeService.getInstance().isAuthorized(session, pid, Permission.convert(permission));
741 6253 leinfelder
		response.setStatus(200);
742
		response.setContentType("text/xml");
743
		return result;
744
    }
745
746
    /**
747
     * Register System Metadata without data or metadata object
748
     * @param pid identifier for System Metadata entry
749 6269 leinfelder
     * @throws JiBXException
750
     * @throws FileUploadException
751
     * @throws IOException
752
     * @throws InvalidRequest
753
     * @throws ServiceFailure
754
     * @throws InvalidSystemMetadata
755
     * @throws NotAuthorized
756
     * @throws NotImplemented
757 6367 leinfelder
     * @throws IllegalAccessException
758
     * @throws InstantiationException
759 6253 leinfelder
     */
760 6397 leinfelder
    protected Identifier registerSystemMetadata(String pid) throws ServiceFailure, InvalidRequest, IOException, FileUploadException, JiBXException, NotImplemented, NotAuthorized, InvalidSystemMetadata, InstantiationException, IllegalAccessException {
761 6253 leinfelder
		logMetacat.debug("Entering registerSystemMetadata: " + pid);
762
763 6269 leinfelder
		// get the system metadata from the request
764
		SystemMetadata systemMetadata = collectSystemMetadata();
765 6253 leinfelder
766 6269 leinfelder
		Identifier guid = new Identifier();
767
		guid.setValue(pid);
768
		logMetacat.debug("registering system metadata with pid " + guid.getValue());
769 6397 leinfelder
		Identifier retGuid = CNodeService.getInstance().registerSystemMetadata(session, guid, systemMetadata);
770 6269 leinfelder
771
		response.setStatus(200);
772
		response.setContentType("text/xml");
773 6397 leinfelder
		return retGuid;
774 6269 leinfelder
775 6253 leinfelder
	}
776 6268 leinfelder
777
    /**
778
     * set the access perms on a document
779 6270 leinfelder
     * @throws JiBXException
780
     * @throws InvalidRequest
781
     * @throws NotImplemented
782
     * @throws NotAuthorized
783
     * @throws NotFound
784
     * @throws ServiceFailure
785
     * @throws InvalidToken
786 6367 leinfelder
     * @throws IllegalAccessException
787
     * @throws InstantiationException
788
     * @throws IOException
789 6268 leinfelder
     */
790 6367 leinfelder
    protected void setAccess() throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException, InstantiationException, IllegalAccessException {
791 6270 leinfelder
792
        String guid = params.get("guid")[0];
793
        Identifier id = new Identifier();
794
        id.setValue(guid);
795
        String accesspolicy = params.get("accesspolicy")[0];
796 6367 leinfelder
        AccessPolicy accessPolicy = TypeMarshaller.unmarshalTypeFromStream(AccessPolicy.class, new ByteArrayInputStream(accesspolicy.getBytes("UTF-8")));
797 6270 leinfelder
        CNodeService.getInstance().setAccessPolicy(session, id, accessPolicy);
798
799 6268 leinfelder
    }
800
801
    /**
802 6282 leinfelder
     *	Pass to the CN search service
803
     *
804
     * @throws NotImplemented
805
     * @throws InvalidRequest
806
     * @throws NotAuthorized
807
     * @throws ServiceFailure
808
     * @throws InvalidToken
809 6268 leinfelder
     * @throws Exception
810
     */
811 6282 leinfelder
    private void query() throws InvalidToken, ServiceFailure, NotAuthorized, InvalidRequest, NotImplemented {
812
813
    	String query = null;
814 6397 leinfelder
		String queryType = null;
815 6282 leinfelder
		try {
816
			query = params.get("query")[0];
817
		} catch (Exception e) {
818
			logMetacat.warn("query not specified");
819
		}
820
		try {
821
			String qt = params.get("queryType")[0];
822 6397 leinfelder
			queryType = qt;
823 6282 leinfelder
		} catch (Exception e) {
824
			logMetacat.warn("queryType not specified");
825
		}
826
827
    	// expecting to throw NotImplemented
828
		CNodeService.getInstance().search(session, queryType, query);
829 6268 leinfelder
    }
830
831 6253 leinfelder
}