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