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 6622 leinfelder
import java.util.Enumeration;
33 6253 leinfelder
import java.util.Map;
34
35
import javax.servlet.ServletContext;
36
import javax.servlet.http.HttpServletRequest;
37
import javax.servlet.http.HttpServletResponse;
38 6514 leinfelder
import javax.xml.parsers.ParserConfigurationException;
39 6253 leinfelder
40 6269 leinfelder
import org.apache.commons.fileupload.FileUploadException;
41 6253 leinfelder
import org.apache.commons.io.IOUtils;
42
import org.apache.log4j.Logger;
43
import org.dataone.client.ObjectFormatCache;
44 6634 cjones
import org.dataone.mimemultipart.MultipartRequest;
45
import org.dataone.mimemultipart.MultipartRequestResolver;
46 6253 leinfelder
import org.dataone.service.exceptions.BaseException;
47
import org.dataone.service.exceptions.IdentifierNotUnique;
48
import org.dataone.service.exceptions.InsufficientResources;
49
import org.dataone.service.exceptions.InvalidRequest;
50
import org.dataone.service.exceptions.InvalidSystemMetadata;
51
import org.dataone.service.exceptions.InvalidToken;
52
import org.dataone.service.exceptions.NotAuthorized;
53
import org.dataone.service.exceptions.NotFound;
54
import org.dataone.service.exceptions.NotImplemented;
55
import org.dataone.service.exceptions.ServiceFailure;
56
import org.dataone.service.exceptions.UnsupportedType;
57 6869 cjones
import org.dataone.service.exceptions.VersionMismatch;
58 6366 leinfelder
import org.dataone.service.types.v1.AccessPolicy;
59
import org.dataone.service.types.v1.Checksum;
60 6803 leinfelder
import org.dataone.service.types.v1.ChecksumAlgorithmList;
61
import org.dataone.service.types.v1.DescribeResponse;
62 6366 leinfelder
import org.dataone.service.types.v1.Event;
63
import org.dataone.service.types.v1.Identifier;
64
import org.dataone.service.types.v1.Log;
65 6592 cjones
import org.dataone.service.types.v1.NodeReference;
66 6366 leinfelder
import org.dataone.service.types.v1.ObjectFormat;
67
import org.dataone.service.types.v1.ObjectFormatIdentifier;
68
import org.dataone.service.types.v1.ObjectFormatList;
69 6622 leinfelder
import org.dataone.service.types.v1.ObjectList;
70 6366 leinfelder
import org.dataone.service.types.v1.ObjectLocationList;
71
import org.dataone.service.types.v1.Permission;
72 6592 cjones
import org.dataone.service.types.v1.Replica;
73
import org.dataone.service.types.v1.ReplicationPolicy;
74
import org.dataone.service.types.v1.ReplicationStatus;
75 6366 leinfelder
import org.dataone.service.types.v1.Subject;
76
import org.dataone.service.types.v1.SystemMetadata;
77 6803 leinfelder
import org.dataone.service.util.Constants;
78 6469 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
79 6367 leinfelder
import org.dataone.service.util.TypeMarshaller;
80 6253 leinfelder
import org.jibx.runtime.JiBXException;
81 6514 leinfelder
import org.xml.sax.SAXException;
82 6253 leinfelder
83
import edu.ucsb.nceas.metacat.dataone.CNodeService;
84 6803 leinfelder
import edu.ucsb.nceas.metacat.dataone.MNodeService;
85 6639 leinfelder
import edu.ucsb.nceas.metacat.properties.PropertyService;
86
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
87 6253 leinfelder
88
/**
89
 * CN REST service implementation handler
90
 *
91 6756 cjones
 * ****************** CNCore -- DONE create() - POST /d1/cn/object/PID
92
 * listFormats() - GET /d1/cn/formats getFormat() - GET /d1/cn/formats/FMTID
93
 * getLogRecords - GET /d1/cn/log reserveIdentifier() - POST /d1/cn/reserve
94
 * listNodes() - Not implemented registerSystemMetadata() - POST /d1/meta/PID
95
 *
96
 * CNRead -- DONE get() - GET /d1/cn/object/PID getSystemMetadata() - GET
97
 * /d1/cn/meta/PID resolve() - GET /d1/cn/resolve/PID assertRelation() - GET
98
 * /d1/cn/assertRelation/PID getChecksum() - GET /d1/cn/checksum search() - Not
99
 * implemented in Metacat
100
 *
101
 * CNAuthorization setOwner() - PUT /d1/cn/owner/PID isAuthorized() - GET
102
 * /d1/cn/isAuthorized/PID setAccessPolicy() - POST /d1/cn/accessRules
103
 *
104
 * CNIdentity - not implemented at all on Metacat
105
 *
106
 * CNReplication setReplicationStatus() - PUT /replicaNotifications/PID
107
 * updateReplicationMetadata() - PUT /replicaMetadata/PID setReplicationPolicy()
108
 * - PUT /replicaPolicies/PID isNodeAuthorized() - GET
109
 * /replicaAuthorizations/PID
110
 *
111
 * CNRegister -- not implemented at all in Metacat ******************
112
 *
113 6253 leinfelder
 * @author leinfelder
114 6756 cjones
 *
115 6253 leinfelder
 */
116 6267 leinfelder
public class CNResourceHandler extends D1ResourceHandler {
117 6253 leinfelder
118 6756 cjones
    /** CN-specific operations **/
119 6253 leinfelder
    protected static final String RESOURCE_RESERVE = "reserve";
120 6271 leinfelder
    protected static final String RESOURCE_FORMATS = "formats";
121 6253 leinfelder
    protected static final String RESOURCE_RESOLVE = "resolve";
122
    protected static final String RESOURCE_OWNER = "owner";
123 6592 cjones
    protected static final String RESOURCE_REPLICATION_POLICY = "replicaPolicies";
124
    protected static final String RESOURCE_REPLICATION_META = "replicaMetadata";
125
    protected static final String RESOURCE_REPLICATION_AUTHORIZED = "replicaAuthorizations";
126
    protected static final String RESOURCE_REPLICATION_NOTIFY = "replicaNotifications";
127 6756 cjones
128 6253 leinfelder
    public CNResourceHandler(ServletContext servletContext,
129 6756 cjones
            HttpServletRequest request, HttpServletResponse response) {
130
        super(servletContext, request, response);
131 6253 leinfelder
        logMetacat = Logger.getLogger(CNResourceHandler.class);
132 6756 cjones
    }
133 6253 leinfelder
134 6756 cjones
    /**
135
     * This function is called from REST API servlet and handles each request to
136
     * the servlet
137 6253 leinfelder
     *
138 6756 cjones
     * @param httpVerb
139
     *            (GET, POST, PUT or DELETE)
140 6253 leinfelder
     */
141 6271 leinfelder
    @Override
142 6253 leinfelder
    public void handle(byte httpVerb) {
143 6756 cjones
        // prepare the handler
144
        super.handle(httpVerb);
145
146 6253 leinfelder
        try {
147 6282 leinfelder
148 6756 cjones
            // get the resource
149 6282 leinfelder
            String resource = request.getPathInfo();
150
            resource = resource.substring(resource.indexOf("/") + 1);
151 6756 cjones
152 6396 leinfelder
            // for the rest of the resouce
153 6282 leinfelder
            String extra = null;
154 6756 cjones
155
            logMetacat.debug("handling verb " + httpVerb
156
                    + " request with resource '" + resource + "'");
157 6253 leinfelder
            boolean status = false;
158 6271 leinfelder
159 6253 leinfelder
            if (resource != null) {
160
161 6756 cjones
                if (resource.startsWith(RESOURCE_ACCESS_RULES)
162
                        && httpVerb == PUT) {
163 6253 leinfelder
                    logMetacat.debug("Setting access policy");
164 6514 leinfelder
                    // after the command
165
                    extra = parseTrailing(resource, RESOURCE_ACCESS_RULES);
166
                    setAccess(extra);
167 6253 leinfelder
                    status = true;
168
                    logMetacat.debug("done setting access");
169 6756 cjones
170 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_META)) {
171 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_META);
172 6756 cjones
173 6396 leinfelder
                    // after the command
174
                    extra = parseTrailing(resource, RESOURCE_META);
175 6756 cjones
176 6253 leinfelder
                    // get
177
                    if (httpVerb == GET) {
178 6282 leinfelder
                        getSystemMetadataObject(extra);
179 6253 leinfelder
                        status = true;
180
                    }
181
                    // post to register system metadata
182
                    if (httpVerb == POST) {
183 6756 cjones
                        registerSystemMetadata(extra);
184
                        status = true;
185 6253 leinfelder
                    }
186
187 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESERVE)) {
188 6253 leinfelder
                    // reserve the ID (in params)
189
                    if (httpVerb == POST) {
190 6756 cjones
                        reserve();
191
                        status = true;
192 6253 leinfelder
                    }
193 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_RESOLVE)) {
194 6756 cjones
195
                    // after the command
196 6396 leinfelder
                    extra = parseTrailing(resource, RESOURCE_RESOLVE);
197 6756 cjones
198 6253 leinfelder
                    // resolve the object location
199
                    if (httpVerb == GET) {
200 6756 cjones
                        resolve(extra);
201
                        status = true;
202 6253 leinfelder
                    }
203 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OWNER)) {
204 6756 cjones
205
                    // after the command
206 6396 leinfelder
                    extra = parseTrailing(resource, RESOURCE_OWNER);
207 6756 cjones
208 6253 leinfelder
                    // set the owner
209
                    if (httpVerb == PUT) {
210 6756 cjones
                        owner(extra);
211
                        status = true;
212
                    }
213 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_IS_AUTHORIZED)) {
214 6756 cjones
215
                    // after the command
216 6396 leinfelder
                    extra = parseTrailing(resource, RESOURCE_IS_AUTHORIZED);
217 6756 cjones
218 6253 leinfelder
                    // authorized?
219
                    if (httpVerb == GET) {
220 6756 cjones
                        isAuthorized(extra);
221
                        status = true;
222
                    }
223 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_OBJECTS)) {
224 6253 leinfelder
                    logMetacat.debug("Using resource 'object'");
225 6756 cjones
                    logMetacat
226
                            .debug("D1 Rest: Starting resource processing...");
227
228 6396 leinfelder
                    // after the command
229
                    extra = parseTrailing(resource, RESOURCE_OBJECTS);
230 6756 cjones
231 6282 leinfelder
                    logMetacat.debug("objectId: " + extra);
232 6253 leinfelder
                    logMetacat.debug("verb:" + httpVerb);
233
234
                    if (httpVerb == GET) {
235 6756 cjones
                        if (extra != null) {
236
                            getObject(extra);
237
                        } else {
238
                            listObjects();
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 6803 leinfelder
                    } else if (httpVerb == HEAD) {
245
                        describeObject(extra);
246
                        status = true;
247 6253 leinfelder
                    }
248 6756 cjones
249 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_FORMATS)) {
250 6756 cjones
                    logMetacat.debug("Using resource: " + RESOURCE_FORMATS);
251
252
                    // after the command
253
                    extra = parseTrailing(resource, RESOURCE_FORMATS);
254
255
                    // handle each verb
256
                    if (httpVerb == GET) {
257
                        if (extra == null) {
258
                            // list the formats collection
259
                            listFormats();
260
                        } else {
261
                            // get the specified format
262
                            getFormat(extra);
263
                        }
264
                        status = true;
265
                    }
266
267 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_LOG)) {
268 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_LOG);
269 6756 cjones
                    // handle log events
270 6253 leinfelder
                    if (httpVerb == GET) {
271
                        getLog();
272
                        status = true;
273
                    }
274
275 6282 leinfelder
                } else if (resource.startsWith(RESOURCE_CHECKSUM)) {
276 6253 leinfelder
                    logMetacat.debug("Using resource: " + RESOURCE_CHECKSUM);
277 6756 cjones
278 6396 leinfelder
                    // after the command
279
                    extra = parseTrailing(resource, RESOURCE_CHECKSUM);
280 6756 cjones
281
                    // handle checksum requests
282 6253 leinfelder
                    if (httpVerb == GET) {
283 6756 cjones
284 6282 leinfelder
                        checksum(extra);
285 6253 leinfelder
                        status = true;
286 6756 cjones
287 6253 leinfelder
                    }
288 6756 cjones
289
                } else if (resource.startsWith(RESOURCE_REPLICATION_POLICY)
290
                        && httpVerb == PUT) {
291
292
                    logMetacat.debug("Using resource: "
293
                            + RESOURCE_REPLICATION_POLICY);
294 6592 cjones
                    // get the trailing pid
295
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_POLICY);
296
                    setReplicationPolicy(extra);
297
                    status = true;
298
299 6756 cjones
                } else if (resource.startsWith(RESOURCE_REPLICATION_META)
300
                        && httpVerb == PUT) {
301
302
                    logMetacat.debug("Using resource: "
303
                            + RESOURCE_REPLICATION_META);
304 6592 cjones
                    // get the trailing pid
305
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_META);
306
                    updateReplicationMetadata(extra);
307
                    status = true;
308
309 6756 cjones
                } else if (resource.startsWith(RESOURCE_REPLICATION_NOTIFY)
310
                        && httpVerb == PUT) {
311
312
                    logMetacat.debug("Using resource: "
313
                            + RESOURCE_REPLICATION_NOTIFY);
314 6592 cjones
                    // get the trailing pid
315
                    extra = parseTrailing(resource, RESOURCE_REPLICATION_NOTIFY);
316
                    setReplicationStatus(extra);
317
                    status = true;
318 6756 cjones
319
                } else if (resource.startsWith(RESOURCE_REPLICATION_AUTHORIZED)
320 6592 cjones
                        && httpVerb == GET) {
321 6756 cjones
322
                    logMetacat.debug("Using resource: "
323
                            + RESOURCE_REPLICATION_AUTHORIZED);
324 6592 cjones
                    // get the trailing pid
325 6756 cjones
                    extra = parseTrailing(resource,
326
                            RESOURCE_REPLICATION_AUTHORIZED);
327 6592 cjones
                    isNodeAuthorized(extra);
328
                    status = true;
329 6756 cjones
330 6803 leinfelder
                } else if (resource.startsWith(Constants.RESOURCE_MONITOR_PING)) {
331
                    if (httpVerb == GET) {
332
                    	// after the command
333
                        extra = parseTrailing(resource, Constants.RESOURCE_MONITOR_PING);
334
335
                        logMetacat.debug("processing ping request");
336
                        Date result = CNodeService.getInstance(request).ping();
337
                        // TODO: send to output
338
                        status = true;
339
                    }
340
                } else if (resource.startsWith(Constants.RESOURCE_CHECKSUM)) {
341
                    if (httpVerb == GET) {
342
                        listChecksumAlgorithms();
343
                        status = true;
344
                    }
345 6890 leinfelder
                } else if (resource.startsWith(Constants.RESOURCE_META_OBSOLETEDBY)
346
                        && httpVerb == PUT) {
347
348
                    logMetacat.debug("Using resource: "
349
                            + Constants.RESOURCE_META_OBSOLETEDBY);
350
                    // get the trailing pid
351
                    extra = parseTrailing(resource, Constants.RESOURCE_META_OBSOLETEDBY);
352
                    setObsoletedBy(extra);
353
                    status = true;
354
355 6756 cjones
                }
356
357 6253 leinfelder
                if (!status) {
358 6756 cjones
                    throw new ServiceFailure("0000", "Unknown error, status = "
359
                            + status);
360 6253 leinfelder
                }
361
            } else {
362 6756 cjones
                throw new InvalidRequest("0000", "No resource matched for "
363
                        + resource);
364 6253 leinfelder
            }
365
        } catch (BaseException be) {
366 6756 cjones
            // report Exceptions as clearly and generically as possible
367
            OutputStream out = null;
368
            try {
369
                out = response.getOutputStream();
370
            } catch (IOException ioe) {
371
                logMetacat.error("Could not get output stream from response",
372
                        ioe);
373
            }
374 6253 leinfelder
            serializeException(be, out);
375
        } catch (Exception e) {
376 6270 leinfelder
            // report Exceptions as clearly and generically as possible
377 6253 leinfelder
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
378 6756 cjones
            OutputStream out = null;
379
            try {
380
                out = response.getOutputStream();
381
            } catch (IOException ioe) {
382
                logMetacat.error("Could not get output stream from response",
383
                        ioe);
384
            }
385
            ServiceFailure se = new ServiceFailure("0000", e.getMessage());
386 6270 leinfelder
            serializeException(se, out);
387 6253 leinfelder
        }
388
    }
389 6756 cjones
390 6270 leinfelder
    /**
391
     * Get the checksum for the given guid
392
     *
393
     * @param guid
394 6756 cjones
     * @throws NotImplemented
395
     * @throws InvalidRequest
396
     * @throws NotFound
397
     * @throws NotAuthorized
398
     * @throws ServiceFailure
399
     * @throws InvalidToken
400
     * @throws IOException
401
     * @throws JiBXException
402 6270 leinfelder
     */
403 6756 cjones
    private void checksum(String guid) throws InvalidToken, ServiceFailure,
404
            NotAuthorized, NotFound, InvalidRequest, NotImplemented,
405
            JiBXException, IOException {
406
        Identifier guidid = new Identifier();
407 6270 leinfelder
        guidid.setValue(guid);
408
        logMetacat.debug("getting checksum for object " + guid);
409 6756 cjones
        Checksum c = CNodeService.getInstance(request).getChecksum(session,
410
                guidid);
411 6270 leinfelder
        logMetacat.debug("got checksum " + c.getValue());
412
        response.setStatus(200);
413
        logMetacat.debug("serializing response");
414 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(c, response.getOutputStream());
415 6270 leinfelder
        logMetacat.debug("done serializing response.");
416 6756 cjones
417 6270 leinfelder
    }
418 6756 cjones
419
    /**
420
     * get the logs based on passed params. Available params are token,
421
     * fromDate, toDate, event. See
422
     * http://mule1.dataone.org/ArchitectureDocs/mn_api_crud
423
     * .html#MN_crud.getLogRecords for more info
424
     *
425
     * @throws NotImplemented
426
     * @throws InvalidRequest
427
     * @throws NotAuthorized
428
     * @throws ServiceFailure
429
     * @throws InvalidToken
430
     * @throws IOException
431
     * @throws JiBXException
432 6253 leinfelder
     */
433 6756 cjones
    private void getLog() throws InvalidToken, ServiceFailure, NotAuthorized,
434
            InvalidRequest, NotImplemented, IOException, JiBXException {
435
436 6270 leinfelder
        Date fromDate = null;
437
        Date toDate = null;
438
        Event event = null;
439
        Integer start = null;
440
        Integer count = null;
441 6756 cjones
442 6270 leinfelder
        try {
443 6756 cjones
            String fromDateS = params.get("fromDate")[0];
444 6272 leinfelder
            logMetacat.debug("param fromDateS: " + fromDateS);
445 6469 leinfelder
            fromDate = DateTimeMarshaller.deserializeDateToUTC(fromDateS);
446 6270 leinfelder
        } catch (Exception e) {
447 6756 cjones
            logMetacat.warn("Could not parse fromDate: " + e.getMessage());
448 6253 leinfelder
        }
449 6270 leinfelder
        try {
450 6756 cjones
            String toDateS = params.get("toDate")[0];
451 6272 leinfelder
            logMetacat.debug("param toDateS: " + toDateS);
452 6469 leinfelder
            toDate = DateTimeMarshaller.deserializeDateToUTC(toDateS);
453 6270 leinfelder
        } catch (Exception e) {
454 6756 cjones
            logMetacat.warn("Could not parse toDate: " + e.getMessage());
455
        }
456 6270 leinfelder
        try {
457 6756 cjones
            String eventS = params.get("event")[0];
458 6270 leinfelder
            event = Event.convert(eventS);
459
        } catch (Exception e) {
460 6756 cjones
            logMetacat.warn("Could not parse event: " + e.getMessage());
461
        }
462 6272 leinfelder
        logMetacat.debug("fromDate: " + fromDate + " toDate: " + toDate);
463 6756 cjones
464 6270 leinfelder
        try {
465 6756 cjones
            start = Integer.parseInt(params.get("start")[0]);
466 6270 leinfelder
        } catch (Exception e) {
467 6756 cjones
            logMetacat.warn("Could not parse start: " + e.getMessage());
468
        }
469 6270 leinfelder
        try {
470 6756 cjones
            count = Integer.parseInt(params.get("count")[0]);
471 6270 leinfelder
        } catch (Exception e) {
472 6756 cjones
            logMetacat.warn("Could not parse count: " + e.getMessage());
473
        }
474
475 6272 leinfelder
        logMetacat.debug("calling getLogRecords");
476 6756 cjones
        Log log = CNodeService.getInstance(request).getLogRecords(session,
477
                fromDate, toDate, event, start, count);
478
479 6270 leinfelder
        OutputStream out = response.getOutputStream();
480
        response.setStatus(200);
481
        response.setContentType("text/xml");
482 6756 cjones
483 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(log, out);
484 6756 cjones
485 6253 leinfelder
    }
486
487
    /**
488
     * Implements REST version of DataONE CRUD API --> get
489 6756 cjones
     *
490
     * @param guid
491
     *            ID of data object to be read
492
     * @throws NotImplemented
493
     * @throws InvalidRequest
494
     * @throws NotFound
495
     * @throws NotAuthorized
496
     * @throws ServiceFailure
497
     * @throws InvalidToken
498
     * @throws IOException
499 6253 leinfelder
     */
500 6756 cjones
    protected void getObject(String guid) throws InvalidToken, ServiceFailure,
501
            NotAuthorized, NotFound, InvalidRequest, NotImplemented,
502
            IOException {
503 6270 leinfelder
504 6280 leinfelder
        Identifier id = new Identifier();
505
        id.setValue(guid);
506 6756 cjones
507
        SystemMetadata sm = CNodeService.getInstance(request)
508
                .getSystemMetadata(session, id);
509
510
        // set the content type
511
        if (sm.getFormatId()
512
                .getValue()
513
                .trim()
514
                .equals(ObjectFormatCache.getInstance().getFormat("text/csv")
515
                        .getFormatId().getValue())) {
516 6280 leinfelder
            response.setContentType("text/csv");
517 6756 cjones
            response.setHeader("Content-Disposition",
518
                    "inline; filename=" + id.getValue() + ".csv");
519
        } else if (sm
520
                .getFormatId()
521
                .getValue()
522
                .trim()
523
                .equals(ObjectFormatCache.getInstance().getFormat("text/plain")
524
                        .getFormatId().getValue())) {
525 6280 leinfelder
            response.setContentType("text/plain");
526 6756 cjones
            response.setHeader("Content-Disposition",
527
                    "inline; filename=" + id.getValue() + ".txt");
528
        } else if (sm
529
                .getFormatId()
530
                .getValue()
531
                .trim()
532
                .equals(ObjectFormatCache.getInstance()
533
                        .getFormat("application/octet-stream").getFormatId()
534
                        .getValue())) {
535 6280 leinfelder
            response.setContentType("application/octet-stream");
536 6756 cjones
        } else {
537 6280 leinfelder
            response.setContentType("text/xml");
538 6756 cjones
            response.setHeader("Content-Disposition",
539
                    "inline; filename=" + id.getValue() + ".xml");
540 6280 leinfelder
        }
541 6756 cjones
542 6542 leinfelder
        InputStream data = CNodeService.getInstance(request).get(session, id);
543 6756 cjones
544 6280 leinfelder
        OutputStream out = response.getOutputStream();
545
        response.setStatus(200);
546
        IOUtils.copyLarge(data, out);
547 6756 cjones
548 6253 leinfelder
    }
549
550
    /**
551
     * Implements REST version of DataONE CRUD API --> getSystemMetadata
552 6756 cjones
     *
553
     * @param guid
554
     *            ID of data object to be read
555
     * @throws NotImplemented
556
     * @throws InvalidRequest
557
     * @throws NotFound
558
     * @throws NotAuthorized
559
     * @throws ServiceFailure
560
     * @throws InvalidToken
561
     * @throws IOException
562
     * @throws JiBXException
563 6253 leinfelder
     */
564 6756 cjones
    protected void getSystemMetadataObject(String guid) throws InvalidToken,
565
            ServiceFailure, NotAuthorized, NotFound, InvalidRequest,
566
            NotImplemented, IOException, JiBXException {
567 6270 leinfelder
568
        Identifier id = new Identifier();
569
        id.setValue(guid);
570 6756 cjones
        SystemMetadata sysmeta = CNodeService.getInstance(request)
571
                .getSystemMetadata(session, id);
572
573 6270 leinfelder
        response.setContentType("text/xml");
574
        response.setStatus(200);
575
        OutputStream out = response.getOutputStream();
576 6756 cjones
577 6270 leinfelder
        // Serialize and write it to the output stream
578 6367 leinfelder
        TypeMarshaller.marshalTypeToOutputStream(sysmeta, out);
579 6756 cjones
    }
580
581 6253 leinfelder
    /**
582 6756 cjones
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler >
583
     * handleInsertOrUpdateAction
584 6253 leinfelder
     *
585 6756 cjones
     * @param guid
586
     *            - ID of data object to be inserted or updated. If action is
587
     *            update, the pid is the existing pid. If insert, the pid is the
588
     *            new one
589
     * @throws InvalidRequest
590
     * @throws ServiceFailure
591
     * @throws IdentifierNotUnique
592
     * @throws JiBXException
593
     * @throws NotImplemented
594
     * @throws InvalidSystemMetadata
595
     * @throws InsufficientResources
596
     * @throws UnsupportedType
597
     * @throws NotAuthorized
598
     * @throws InvalidToken
599
     * @throws IOException
600
     * @throws IllegalAccessException
601
     * @throws InstantiationException
602 6253 leinfelder
     */
603 6756 cjones
    protected void putObject(String pid, String action) throws ServiceFailure,
604
            InvalidRequest, IdentifierNotUnique, JiBXException, InvalidToken,
605
            NotAuthorized, UnsupportedType, InsufficientResources,
606
            InvalidSystemMetadata, NotImplemented, IOException,
607
            InstantiationException, IllegalAccessException {
608 6253 leinfelder
        logMetacat.debug("Entering putObject: " + pid + "/" + action);
609 6756 cjones
610 6269 leinfelder
        // Read the incoming data from its Mime Multipart encoding
611 6756 cjones
        Map<String, File> files = collectMultipartFiles();
612 6269 leinfelder
        InputStream object = null;
613
        InputStream sysmeta = null;
614 6253 leinfelder
615 6269 leinfelder
        File smFile = files.get("sysmeta");
616
        sysmeta = new FileInputStream(smFile);
617
        File objFile = files.get("object");
618
        object = new FileInputStream(objFile);
619 6253 leinfelder
620 6756 cjones
        if (action.equals(FUNCTION_NAME_INSERT)) { // handle inserts
621
622 6269 leinfelder
            logMetacat.debug("Commence creation...");
623 6756 cjones
            SystemMetadata smd = TypeMarshaller.unmarshalTypeFromStream(
624
                    SystemMetadata.class, sysmeta);
625 6253 leinfelder
626 6269 leinfelder
            Identifier id = new Identifier();
627
            id.setValue(pid);
628
            logMetacat.debug("creating object with pid " + id.getValue());
629 6756 cjones
            Identifier rId = CNodeService.getInstance(request).create(session,
630
                    id, object, smd);
631
632 6269 leinfelder
            OutputStream out = response.getOutputStream();
633
            response.setStatus(200);
634
            response.setContentType("text/xml");
635 6756 cjones
636 6367 leinfelder
            TypeMarshaller.marshalTypeToOutputStream(rId, out);
637 6756 cjones
638 6269 leinfelder
        } else {
639
            throw new InvalidRequest("1000", "Operation must be create.");
640 6253 leinfelder
        }
641
    }
642
643
    /**
644
     * List the object formats registered with the system
645 6756 cjones
     *
646
     * @throws NotImplemented
647
     * @throws InsufficientResources
648
     * @throws NotFound
649
     * @throws ServiceFailure
650
     * @throws InvalidRequest
651
     * @throws IOException
652
     * @throws JiBXException
653 6253 leinfelder
     */
654 6756 cjones
    private void listFormats() throws InvalidRequest, ServiceFailure, NotFound,
655
            InsufficientResources, NotImplemented, IOException, JiBXException {
656
        logMetacat.debug("Entering listFormats()");
657 6270 leinfelder
658 6756 cjones
        ObjectFormatList objectFormatList = CNodeService.getInstance(request)
659
                .listFormats();
660
        // get the response output stream
661
        OutputStream out = response.getOutputStream();
662
        response.setStatus(200);
663
        response.setContentType("text/xml");
664
665
        // style the object with a processing directive
666
        String stylesheet = null;
667
        try {
668
            stylesheet = PropertyService.getProperty("dataone.types.xsl");
669
        } catch (PropertyNotFoundException e) {
670
            logMetacat.warn("Could not locate DataONE types XSLT: "
671
                    + e.getMessage());
672
        }
673
674
        TypeMarshaller.marshalTypeToOutputStream(objectFormatList, out,
675
                stylesheet);
676
677 6253 leinfelder
    }
678 6803 leinfelder
679
    private void listChecksumAlgorithms() throws IOException, ServiceFailure,
680
			NotImplemented, JiBXException {
681
		logMetacat.debug("Entering listFormats()");
682 6253 leinfelder
683 6803 leinfelder
		ChecksumAlgorithmList result = CNodeService.getInstance(request).listChecksumAlgorithms();
684
685
		// get the response output stream
686
		OutputStream out = response.getOutputStream();
687
		response.setStatus(200);
688
		response.setContentType("text/xml");
689
690
		// style the object with a processing directive
691
		String stylesheet = null;
692
		try {
693
			stylesheet = PropertyService.getProperty("dataone.types.xsl");
694
		} catch (PropertyNotFoundException e) {
695
			logMetacat.warn("Could not locate DataONE types XSLT: "
696
					+ e.getMessage());
697
		}
698
699
		TypeMarshaller.marshalTypeToOutputStream(result, out, stylesheet);
700
701
	}
702
703 6756 cjones
    /**
704 6803 leinfelder
     * http://mule1.dataone.org/ArchitectureDocs-current/apis/CN_APIs.html#CNRead.describe
705
     * @param pid
706
     * @throws InvalidToken
707
     * @throws ServiceFailure
708
     * @throws NotAuthorized
709
     * @throws NotFound
710
     * @throws NotImplemented
711
     * @throws InvalidRequest
712
     */
713
    private void describeObject(String pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, InvalidRequest
714
    {
715
        response.setStatus(200);
716
        response.setContentType("text/xml");
717
718
        Identifier id = new Identifier();
719
        id.setValue(pid);
720
721
        DescribeResponse dr = CNodeService.getInstance(request).describe(session, id);
722
        //response.addHeader("pid", pid);
723
        response.addHeader("DataONE-Checksum", dr.getDataONE_Checksum().getAlgorithm() + "," + dr.getDataONE_Checksum().getValue());
724
        response.addHeader("Content-Length", dr.getContent_Length() + "");
725
        response.addHeader("Last-Modified", DateTimeMarshaller.serializeDateToUTC(dr.getLast_Modified()));
726
        response.addHeader("DataONE-ObjectFormat", dr.getDataONE_ObjectFormatIdentifier().getValue());
727
        response.addHeader("DataONE-SerialVersion", dr.getSerialVersion().toString());
728
729
    }
730
731
    /**
732 6253 leinfelder
     * Return the requested object format
733
     *
734 6756 cjones
     * @param fmtidStr
735
     *            the requested format identifier as a string
736
     * @throws NotImplemented
737
     * @throws InsufficientResources
738
     * @throws NotFound
739
     * @throws ServiceFailure
740
     * @throws InvalidRequest
741
     * @throws IOException
742
     * @throws JiBXException
743 6253 leinfelder
     */
744 6756 cjones
    private void getFormat(String fmtidStr) throws InvalidRequest,
745
            ServiceFailure, NotFound, InsufficientResources, NotImplemented,
746
            IOException, JiBXException {
747
        logMetacat.debug("Entering listFormats()");
748
749
        ObjectFormatIdentifier fmtid = new ObjectFormatIdentifier();
750
        fmtid.setValue(fmtidStr);
751
752
        // get the specified object format
753
        ObjectFormat objectFormat = CNodeService.getInstance(request)
754
                .getFormat(fmtid);
755
756
        OutputStream out = response.getOutputStream();
757
        response.setStatus(200);
758
        response.setContentType("text/xml");
759
760
        TypeMarshaller.marshalTypeToOutputStream(objectFormat, out);
761
762 6253 leinfelder
    }
763 6756 cjones
764 6253 leinfelder
    /**
765
     * Reserve the given Identifier
766 6756 cjones
     *
767 6253 leinfelder
     * @throws InvalidToken
768
     * @throws ServiceFailure
769
     * @throws NotAuthorized
770
     * @throws IdentifierNotUnique
771
     * @throws NotImplemented
772
     * @throws InvalidRequest
773 6756 cjones
     * @throws IOException
774
     * @throws JiBXException
775 6253 leinfelder
     */
776 6756 cjones
    private void reserve() throws InvalidToken, ServiceFailure, NotAuthorized,
777
            IdentifierNotUnique, NotImplemented, InvalidRequest, IOException,
778
            JiBXException {
779
        Identifier pid = null;
780
        String scope = null;
781
        String format = null;
782
        // gather the params
783
        try {
784
            String id = params.get("pid")[0];
785
            pid = new Identifier();
786
            pid.setValue(id);
787
        } catch (Exception e) {
788
            logMetacat.warn("pid not specified");
789
        }
790
        try {
791
            scope = params.get("scope")[0];
792
        } catch (Exception e) {
793
            logMetacat.warn("pid not specified");
794
        }
795
        try {
796
            format = params.get("format")[0];
797
        } catch (Exception e) {
798
            logMetacat.warn("pid not specified");
799
        }
800
        // call the implementation
801
        Identifier resultPid = CNodeService.getInstance(request)
802
                .reserveIdentifier(session, pid);
803
        OutputStream out = response.getOutputStream();
804
        response.setStatus(200);
805
        response.setContentType("text/xml");
806
        // send back the reserved pid
807
        TypeMarshaller.marshalTypeToOutputStream(resultPid, out);
808 6253 leinfelder
    }
809 6756 cjones
810 6270 leinfelder
    /**
811
     *
812
     * @param id
813
     * @throws InvalidRequest
814
     * @throws InvalidToken
815
     * @throws ServiceFailure
816
     * @throws NotAuthorized
817
     * @throws NotFound
818
     * @throws NotImplemented
819
     * @throws IOException
820 6756 cjones
     * @throws JiBXException
821 6270 leinfelder
     */
822 6756 cjones
    private void resolve(String id) throws InvalidRequest, InvalidToken,
823
            ServiceFailure, NotAuthorized, NotFound, NotImplemented,
824
            IOException, JiBXException {
825
        Identifier pid = new Identifier();
826
        pid.setValue(id);
827
        ObjectLocationList locationList = CNodeService.getInstance(request)
828
                .resolve(session, pid);
829
        OutputStream out = response.getOutputStream();
830
        response.setStatus(200);
831
        response.setContentType("text/xml");
832
        TypeMarshaller.marshalTypeToOutputStream(locationList, out);
833
834 6253 leinfelder
    }
835
836 6270 leinfelder
    /**
837
     * Set the owner of a resource
838 6756 cjones
     *
839 6270 leinfelder
     * @param id
840
     * @throws JiBXException
841
     * @throws InvalidToken
842
     * @throws ServiceFailure
843
     * @throws NotFound
844
     * @throws NotAuthorized
845
     * @throws NotImplemented
846
     * @throws InvalidRequest
847
     * @throws IOException
848 6756 cjones
     * @throws IllegalAccessException
849
     * @throws InstantiationException
850 6869 cjones
     * @throws VersionMismatch
851 6270 leinfelder
     */
852 6756 cjones
    private void owner(String id) throws JiBXException, InvalidToken,
853
            ServiceFailure, NotFound, NotAuthorized, NotImplemented,
854
            InvalidRequest, IOException, InstantiationException,
855 6869 cjones
            IllegalAccessException, VersionMismatch {
856 6756 cjones
857 6592 cjones
        Identifier pid = new Identifier();
858 6756 cjones
        pid.setValue(id);
859 6592 cjones
860
        long serialVersion = 0L;
861
        String serialVersionStr = null;
862 6756 cjones
863 6592 cjones
        // get the serialVersion
864
        try {
865
            serialVersionStr = params.get("serialVersion")[0];
866
            serialVersion = new Long(serialVersionStr).longValue();
867 6756 cjones
868 6592 cjones
        } catch (NullPointerException e) {
869
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
870
            logMetacat.error(msg);
871
            throw new InvalidRequest("4442", msg);
872 6756 cjones
873
        }
874
875
        // get the subject
876
        String subjectStr = params.get("subject")[0];
877
        Subject subject = TypeMarshaller.unmarshalTypeFromStream(Subject.class,
878
                new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
879
880 6803 leinfelder
        Identifier retPid = CNodeService.getInstance(request).setRightsHolder(session, pid, subject, serialVersion);
881 6756 cjones
        OutputStream out = response.getOutputStream();
882
        response.setStatus(200);
883
        response.setContentType("text/xml");
884
        TypeMarshaller.marshalTypeToOutputStream(retPid, out);
885 6253 leinfelder
    }
886 6756 cjones
887 6270 leinfelder
    /**
888
     * Processes the authorization check for given id
889 6756 cjones
     *
890 6270 leinfelder
     * @param id
891
     * @return
892
     * @throws ServiceFailure
893
     * @throws InvalidToken
894
     * @throws NotFound
895
     * @throws NotAuthorized
896
     * @throws NotImplemented
897
     * @throws InvalidRequest
898
     */
899 6756 cjones
    private boolean isAuthorized(String id) throws ServiceFailure,
900
            InvalidToken, NotFound, NotAuthorized, NotImplemented,
901
            InvalidRequest {
902
        Identifier pid = new Identifier();
903
        pid.setValue(id);
904
        String permission = params.get("action")[0];
905
        boolean result = CNodeService.getInstance(request).isAuthorized(
906
                session, pid, Permission.convert(permission));
907
        response.setStatus(200);
908
        response.setContentType("text/xml");
909
        return result;
910 6253 leinfelder
    }
911 6756 cjones
912 6253 leinfelder
    /**
913
     * Register System Metadata without data or metadata object
914 6756 cjones
     *
915
     * @param pid
916
     *            identifier for System Metadata entry
917
     * @throws JiBXException
918
     * @throws FileUploadException
919
     * @throws IOException
920
     * @throws InvalidRequest
921
     * @throws ServiceFailure
922
     * @throws InvalidSystemMetadata
923
     * @throws NotAuthorized
924
     * @throws NotImplemented
925
     * @throws IllegalAccessException
926
     * @throws InstantiationException
927 6253 leinfelder
     */
928 6880 leinfelder
    protected void registerSystemMetadata(String pid)
929 6756 cjones
            throws ServiceFailure, InvalidRequest, IOException,
930
            FileUploadException, JiBXException, NotImplemented, NotAuthorized,
931
            InvalidSystemMetadata, InstantiationException,
932
            IllegalAccessException {
933
        logMetacat.debug("Entering registerSystemMetadata: " + pid);
934 6253 leinfelder
935 6756 cjones
        // get the system metadata from the request
936
        SystemMetadata systemMetadata = collectSystemMetadata();
937 6253 leinfelder
938 6756 cjones
        Identifier guid = new Identifier();
939
        guid.setValue(pid);
940
        logMetacat.debug("registering system metadata with pid "
941
                + guid.getValue());
942
        Identifier retGuid = CNodeService.getInstance(request)
943
                .registerSystemMetadata(session, guid, systemMetadata);
944
945 6880 leinfelder
        OutputStream out = response.getOutputStream();
946 6756 cjones
        response.setStatus(200);
947
        response.setContentType("text/xml");
948 6880 leinfelder
949
        TypeMarshaller.marshalTypeToOutputStream(retGuid, out);
950 6756 cjones
951
    }
952
953 6268 leinfelder
    /**
954
     * set the access perms on a document
955 6756 cjones
     *
956
     * @throws JiBXException
957
     * @throws InvalidRequest
958
     * @throws NotImplemented
959
     * @throws NotAuthorized
960
     * @throws NotFound
961
     * @throws ServiceFailure
962
     * @throws InvalidToken
963
     * @throws IllegalAccessException
964
     * @throws InstantiationException
965
     * @throws IOException
966
     * @throws SAXException
967
     * @throws ParserConfigurationException
968 6869 cjones
     * @throws VersionMismatch
969 6268 leinfelder
     */
970 6756 cjones
    protected void setAccess(String pid) throws JiBXException, InvalidToken,
971
            ServiceFailure, NotFound, NotAuthorized, NotImplemented,
972
            InvalidRequest, IOException, InstantiationException,
973 6869 cjones
            IllegalAccessException, ParserConfigurationException, SAXException, VersionMismatch {
974 6270 leinfelder
975 6592 cjones
        long serialVersion = 0L;
976
        String serialVersionStr = null;
977 6756 cjones
978 6592 cjones
        // get the serialVersion
979
        try {
980
            serialVersionStr = params.get("serialVersion")[0];
981
            serialVersion = new Long(serialVersionStr).longValue();
982 6756 cjones
983 6592 cjones
        } catch (NullPointerException e) {
984
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
985
            logMetacat.error(msg);
986
            throw new InvalidRequest("4402", msg);
987 6756 cjones
988 6592 cjones
        }
989 6756 cjones
990 6270 leinfelder
        Identifier id = new Identifier();
991 6514 leinfelder
        id.setValue(pid);
992 6756 cjones
993 6514 leinfelder
        AccessPolicy accessPolicy = collectAccessPolicy();
994 6756 cjones
        CNodeService.getInstance(request).setAccessPolicy(session, id,
995
                accessPolicy, serialVersion);
996 6270 leinfelder
997 6268 leinfelder
    }
998 6756 cjones
999 6268 leinfelder
    /**
1000 6756 cjones
     * List the objects
1001
     *
1002
     * @throws NotImplemented
1003
     * @throws InvalidRequest
1004
     * @throws NotAuthorized
1005
     * @throws ServiceFailure
1006
     * @throws InvalidToken
1007
     * @throws NotFound
1008
     * @throws IOException
1009 6622 leinfelder
     * @throws JiBXException
1010 6268 leinfelder
     * @throws Exception
1011
     */
1012 6756 cjones
    private void listObjects() throws InvalidToken, ServiceFailure,
1013
            NotAuthorized, InvalidRequest, NotImplemented, NotFound,
1014
            IOException, JiBXException {
1015 6622 leinfelder
1016 6756 cjones
        Date startTime = null;
1017
        Date endTime = null;
1018
        ObjectFormat objectFormat = null;
1019
        boolean replicaStatus = false;
1020
        int start = 0;
1021
        int count = -1;
1022
        Enumeration<String> paramlist = request.getParameterNames();
1023
        while (paramlist.hasMoreElements()) {
1024
            // parse the params and make the call
1025
            String name = paramlist.nextElement();
1026
            String[] value = request.getParameterValues(name);
1027 6622 leinfelder
1028 6756 cjones
            if (name.equals("startTime") && value != null) {
1029
                try {
1030
                    startTime = DateTimeMarshaller
1031
                            .deserializeDateToUTC(value[0]);
1032
                } catch (Exception e) {
1033
                    // if we can't parse it, just don't use the startTime param
1034
                    logMetacat.warn("Could not parse startTime: " + value[0]);
1035
                    startTime = null;
1036
                }
1037
            } else if (name.equals("endTime") && value != null) {
1038
                try {
1039
                    endTime = DateTimeMarshaller.deserializeDateToUTC(value[0]);
1040
                } catch (Exception e) {
1041
                    // if we can't parse it, just don't use the endTime param
1042
                    logMetacat.warn("Could not parse endTime: " + value[0]);
1043
                    endTime = null;
1044
                }
1045
            } else if (name.equals("objectFormat") && value != null) {
1046
                objectFormat = ObjectFormatCache.getInstance().getFormat(
1047
                        value[0]);
1048
            } else if (name.equals("replicaStatus") && value != null) {
1049
                replicaStatus = Boolean.parseBoolean(value[0]);
1050
            } else if (name.equals("start") && value != null) {
1051
                start = Integer.valueOf(value[0]);
1052
            } else if (name.equals("count") && value != null) {
1053
                count = Integer.valueOf(value[0]);
1054
            }
1055
        }
1056
        // make the call
1057
        logMetacat.debug("session: " + session + " startTime: " + startTime
1058
                + " endtime: " + endTime + " objectFormat: " + objectFormat
1059
                + " replicaStatus: " + replicaStatus + " start: " + start
1060
                + " count: " + count);
1061 6622 leinfelder
1062 6756 cjones
        ObjectFormatIdentifier fmtid = null;
1063
        if (objectFormat != null) {
1064
            fmtid = objectFormat.getFormatId();
1065
        }
1066 6622 leinfelder
1067 6756 cjones
        // get the list
1068
        ObjectList ol = CNodeService.getInstance(request).listObjects(session,
1069
                startTime, endTime, fmtid, replicaStatus, start, count);
1070
1071
        // send it
1072
        OutputStream out = response.getOutputStream();
1073
        response.setStatus(200);
1074
        response.setContentType("text/xml");
1075
1076
        // style the object with a processing directive
1077
        String stylesheet = null;
1078
        try {
1079
            stylesheet = PropertyService.getProperty("dataone.types.xsl");
1080
        } catch (PropertyNotFoundException e) {
1081
            logMetacat.warn("Could not locate DataONE types XSLT: "
1082
                    + e.getMessage());
1083
        }
1084
1085
        // Serialize and write it to the output stream
1086
        TypeMarshaller.marshalTypeToOutputStream(ol, out, stylesheet);
1087
    }
1088
1089 6592 cjones
    /**
1090
     * Pass the request to get node replication authorization to CNodeService
1091
     *
1092 6756 cjones
     * @param pid
1093
     *            the identifier of the object to get authorization to replicate
1094 6592 cjones
     *
1095
     * @throws NotImplemented
1096
     * @throws NotAuthorized
1097
     * @throws InvalidToken
1098
     * @throws ServiceFailure
1099
     * @throws NotFound
1100
     * @throws InvalidRequest
1101
     */
1102 6756 cjones
    public boolean isNodeAuthorized(String pid) throws NotImplemented,
1103
            NotAuthorized, InvalidToken, ServiceFailure, NotFound,
1104
            InvalidRequest {
1105
1106 6592 cjones
        boolean result = false;
1107
        Subject targetNodeSubject = new Subject();
1108
        String nodeSubject = null;
1109
        String replPermission = null;
1110 6756 cjones
1111 6592 cjones
        // get the pid
1112
        Identifier identifier = new Identifier();
1113
        identifier.setValue(pid);
1114 6756 cjones
1115 6592 cjones
        // get the target node subject
1116
        try {
1117
            nodeSubject = params.get("targetNodeSubject")[0];
1118
            targetNodeSubject.setValue(nodeSubject);
1119 6756 cjones
1120 6592 cjones
        } catch (NullPointerException e) {
1121
            String msg = "The 'targetNodeSubject' must be provided as a parameter and was not.";
1122
            logMetacat.error(msg);
1123
            throw new InvalidRequest("4873", msg);
1124 6756 cjones
1125 6592 cjones
        }
1126 6756 cjones
1127 6777 leinfelder
        result = CNodeService.getInstance(request).isNodeAuthorized(session, targetNodeSubject, identifier);
1128 6268 leinfelder
1129 6592 cjones
        response.setStatus(200);
1130
        response.setContentType("text/xml");
1131
        return result;
1132 6756 cjones
1133 6592 cjones
    }
1134 6756 cjones
1135 6592 cjones
    /**
1136
     * Pass the request to set the replication policy to CNodeService
1137
     *
1138 6756 cjones
     * @param pid
1139
     *            the identifier of the object to set the replication policy on
1140 6592 cjones
     *
1141
     * @throws NotImplemented
1142
     * @throws NotFound
1143
     * @throws NotAuthorized
1144
     * @throws ServiceFailure
1145
     * @throws InvalidRequest
1146
     * @throws InvalidToken
1147
     * @throws IOException
1148
     * @throws InstantiationException
1149
     * @throws IllegalAccessException
1150
     * @throws JiBXException
1151 6869 cjones
     * @throws VersionMismatch
1152 6592 cjones
     */
1153 6756 cjones
    public boolean setReplicationPolicy(String pid) throws NotImplemented,
1154
            NotFound, NotAuthorized, ServiceFailure, InvalidRequest,
1155
            InvalidToken, IOException, InstantiationException,
1156 6869 cjones
            IllegalAccessException, JiBXException, VersionMismatch {
1157 6756 cjones
1158 6592 cjones
        boolean result = false;
1159
        ReplicationPolicy policy = null;
1160
        long serialVersion = 0L;
1161
        String serialVersionStr = null;
1162 6756 cjones
1163 6592 cjones
        Identifier identifier = new Identifier();
1164
        identifier.setValue(pid);
1165 6756 cjones
1166 6634 cjones
        policy = collectReplicationPolicy();
1167
1168 6592 cjones
        // get the serialVersion
1169
        try {
1170 6603 cjones
            serialVersionStr = multipartparams.get("serialVersion").get(0);
1171 6592 cjones
            serialVersion = new Long(serialVersionStr).longValue();
1172 6756 cjones
1173 6592 cjones
        } catch (NullPointerException e) {
1174
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1175
            logMetacat.error(msg);
1176
            throw new InvalidRequest("4883", msg);
1177 6756 cjones
1178 6592 cjones
        }
1179 6756 cjones
        result = CNodeService.getInstance(request).setReplicationPolicy(
1180
                session, identifier, policy, serialVersion);
1181 6592 cjones
        response.setStatus(200);
1182
        response.setContentType("text/xml");
1183
        return result;
1184 6756 cjones
1185 6592 cjones
    }
1186 6890 leinfelder
1187
    public boolean setObsoletedBy(String pid) throws NotImplemented,
1188
	    NotFound, NotAuthorized, ServiceFailure, InvalidRequest,
1189
	    InvalidToken, IOException, InstantiationException,
1190
	    IllegalAccessException, JiBXException, VersionMismatch {
1191
1192
	boolean result = false;
1193
	long serialVersion = 0L;
1194
	String serialVersionStr = null;
1195
1196
	Identifier identifier = new Identifier();
1197
	identifier.setValue(pid);
1198
1199
	Identifier obsoletedByPid = null;
1200
	try {
1201
		String obsoletedByPidString = params.get("obsoletedByPid")[0];
1202
		obsoletedByPid = new Identifier();
1203
		obsoletedByPid.setValue(obsoletedByPidString);
1204
	} catch (NullPointerException e) {
1205
	    String msg = "The 'obsoletedByPid' must be provided as a parameter and was not.";
1206
	    logMetacat.error(msg);
1207
	    throw new InvalidRequest("4883", msg);
1208
	}
1209
1210
	// get the serialVersion
1211
	try {
1212
	    serialVersionStr = params.get("serialVersion")[0];
1213
	    serialVersion = new Long(serialVersionStr).longValue();
1214
1215
	} catch (NullPointerException e) {
1216
	    String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1217
	    logMetacat.error(msg);
1218
	    throw new InvalidRequest("4883", msg);
1219
1220
	}
1221
	result = CNodeService.getInstance(request).setObsoletedBy(
1222
	        session, identifier, obsoletedByPid, serialVersion);
1223
	response.setStatus(200);
1224
	response.setContentType("text/xml");
1225
	return result;
1226
1227
	}
1228 6756 cjones
1229 6592 cjones
    /**
1230
     * Pass the request to set the replication status to CNodeService
1231
     *
1232 6756 cjones
     * @param pid
1233
     *            the identifier of the object to set the replication status on
1234 6592 cjones
     *
1235
     * @throws ServiceFailure
1236
     * @throws NotImplemented
1237
     * @throws InvalidToken
1238
     * @throws NotAuthorized
1239
     * @throws InvalidRequest
1240
     * @throws NotFound
1241 6794 cjones
     * @throws JiBXException
1242
     * @throws IllegalAccessException
1243
     * @throws InstantiationException
1244
     * @throws IOException
1245 6592 cjones
     */
1246 6756 cjones
    public boolean setReplicationStatus(String pid) throws ServiceFailure,
1247
            NotImplemented, InvalidToken, NotAuthorized, InvalidRequest,
1248
            NotFound {
1249 6794 cjones
1250 6592 cjones
        boolean result = false;
1251
        Identifier identifier = new Identifier();
1252
        identifier.setValue(pid);
1253 6794 cjones
        BaseException failure = null;
1254 6592 cjones
        ReplicationStatus status = null;
1255
        String replicationStatus = null;
1256
        NodeReference targetNodeRef = null;
1257
        String targetNode = null;
1258 6756 cjones
1259 6634 cjones
        // Parse the params out of the multipart form data
1260
        // Read the incoming data from its Mime Multipart encoding
1261 6794 cjones
        logMetacat.debug("Parsing ReplicaStatus from the mime multipart entity");
1262 6634 cjones
1263
        try {
1264 6794 cjones
            failure = collectReplicationStatus();
1265
1266
        } catch (IOException e2) {
1267
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
1268
                e2.getMessage());
1269
1270
        } catch (InstantiationException e2) {
1271
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
1272
                e2.getMessage());
1273
1274
        } catch (IllegalAccessException e2) {
1275
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
1276
                    e2.getMessage());
1277
1278
        } catch (JiBXException e2) {
1279
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
1280
                    e2.getMessage());
1281
1282 6634 cjones
        }
1283 6794 cjones
1284 6592 cjones
        // get the replication status param
1285
        try {
1286 6643 cjones
            replicationStatus = multipartparams.get("status").get(0);
1287 6592 cjones
            status = ReplicationStatus.convert(replicationStatus);
1288 6677 cjones
1289 6642 cjones
        } catch (NullPointerException npe) {
1290
1291 6756 cjones
            logMetacat.debug("The 'status' parameter was not found in the "
1292
                    + "multipartparams map.  Trying the params map.");
1293
1294 6642 cjones
            try {
1295 6643 cjones
                replicationStatus = params.get("status")[0];
1296 6756 cjones
                status = ReplicationStatus.convert(replicationStatus
1297
                        .toLowerCase());
1298
1299 6642 cjones
            } catch (Exception e) {
1300 6643 cjones
                String msg = "The 'status' must be provided as a parameter and was not.";
1301 6642 cjones
                logMetacat.error(msg);
1302
                throw new InvalidRequest("4730", msg);
1303 6756 cjones
1304 6642 cjones
            }
1305 6756 cjones
1306 6592 cjones
        }
1307 6756 cjones
1308 6592 cjones
        // get the target node reference param
1309 6642 cjones
        try {
1310
            targetNode = multipartparams.get("nodeRef").get(0);
1311
            targetNodeRef = new NodeReference();
1312
            targetNodeRef.setValue(targetNode);
1313 6756 cjones
1314 6642 cjones
        } catch (NullPointerException e) {
1315 6756 cjones
            logMetacat.debug("The 'nodeRef' parameter was not found in the "
1316
                    + "multipartparams map.  Trying the params map.");
1317
1318 6642 cjones
            try {
1319
                targetNode = params.get("nodeRef")[0];
1320
                targetNodeRef = new NodeReference();
1321
                targetNodeRef.setValue(targetNode);
1322 6756 cjones
1323 6642 cjones
            } catch (Exception e1) {
1324
                String msg = "The 'nodeRef' must be provided as a parameter and was not.";
1325
                logMetacat.error(msg);
1326
                throw new InvalidRequest("4730", msg);
1327 6756 cjones
1328 6642 cjones
            }
1329 6756 cjones
1330 6642 cjones
        }
1331 6756 cjones
1332
        result = CNodeService.getInstance(request).setReplicationStatus(
1333 6794 cjones
                session, identifier, targetNodeRef, status, failure);
1334 6592 cjones
        response.setStatus(200);
1335
        response.setContentType("text/xml");
1336
        return result;
1337 6756 cjones
1338 6592 cjones
    }
1339 6756 cjones
1340 6592 cjones
    /**
1341
     * Pass the request to update the replication metadata to CNodeService
1342
     *
1343 6756 cjones
     * @param pid
1344
     *            the identifier of the object to update the replication
1345
     *            metadata on
1346 6592 cjones
     *
1347
     * @throws ServiceFailure
1348
     * @throws NotImplemented
1349
     * @throws InvalidToken
1350
     * @throws NotAuthorized
1351
     * @throws InvalidRequest
1352
     * @throws NotFound
1353 6869 cjones
     * @throws VersionMismatch
1354 6592 cjones
     */
1355 6756 cjones
    public boolean updateReplicationMetadata(String pid) throws ServiceFailure,
1356
            NotImplemented, InvalidToken, NotAuthorized, InvalidRequest,
1357 6869 cjones
            NotFound, VersionMismatch {
1358 6592 cjones
1359
        boolean result = false;
1360
        long serialVersion = 0L;
1361
        String serialVersionStr = null;
1362
        Replica replica = null;
1363
        Identifier identifier = new Identifier();
1364
        identifier.setValue(pid);
1365
1366 6634 cjones
        replica = collectReplicaMetadata();
1367 6756 cjones
1368 6592 cjones
        // get the serialVersion
1369
        try {
1370 6603 cjones
            serialVersionStr = multipartparams.get("serialVersion").get(0);
1371 6592 cjones
            serialVersion = new Long(serialVersionStr).longValue();
1372 6756 cjones
1373 6592 cjones
        } catch (NullPointerException e) {
1374
            String msg = "The 'serialVersion' must be provided as a parameter and was not.";
1375
            logMetacat.error(msg);
1376
            throw new InvalidRequest("4853", msg);
1377 6756 cjones
1378 6592 cjones
        }
1379
1380 6756 cjones
        result = CNodeService.getInstance(request).updateReplicationMetadata(
1381
                session, identifier, replica, serialVersion);
1382 6592 cjones
        response.setStatus(200);
1383
        response.setContentType("text/xml");
1384
        return result;
1385
1386
    }
1387
1388 6253 leinfelder
}