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