Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2000 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author: Serhan AKIN $'
7
 *     '$Date: 2009-06-13 15:28:13 +0300  $'
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.BufferedReader;
26
import java.io.IOException;
27
import java.io.InputStream;
28
import java.io.PrintWriter;
29
import java.util.Enumeration;
30
import java.util.Hashtable;
31
import java.util.Timer;
32

    
33
import javax.servlet.ServletContext;
34
import javax.servlet.http.HttpServletRequest;
35
import javax.servlet.http.HttpServletResponse;
36

    
37
import org.apache.commons.io.IOUtils;
38
import org.apache.log4j.Logger;
39
import org.dataone.service.exceptions.BaseException;
40
import org.dataone.service.exceptions.InvalidToken;
41
import org.dataone.service.exceptions.NotAuthorized;
42
import org.dataone.service.exceptions.NotFound;
43
import org.dataone.service.exceptions.NotImplemented;
44
import org.dataone.service.exceptions.ServiceFailure;
45
import org.dataone.service.types.AuthToken;
46
import org.dataone.service.types.IdentifierType;
47

    
48
import edu.ucsb.nceas.metacat.DBUtil;
49
import edu.ucsb.nceas.metacat.IdentifierManager;
50
import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
51
import edu.ucsb.nceas.metacat.MetacatHandler;
52
import edu.ucsb.nceas.metacat.dataone.CrudService;
53
import edu.ucsb.nceas.metacat.util.RequestUtil;
54
import edu.ucsb.nceas.metacat.util.SessionData;
55

    
56
/**
57
 * 
58
 * Implements Earthgrid REST API to Metacat <br/><br/> 
59
 * 
60
 * <ul>
61
 * <li>
62
 * <h3> EarthGrid Query Service</h3>
63
 * <ul><li>
64
 * <h3>Get & Authenticated Get:</h3> 
65
 * is equal to Metacat's read action and returns a data file having
66
 * the specified <doc-id> in the resource path. For authenticated Get service, a session id must be provided 
67
 * in the query string. <br/><br/>
68
 * 
69
 * <b>REST URL:</b>	<code>GET, [context-root]/object/[doc-id]?sessionid=[sessionid] </code><br/>
70
 * <b>Returns:</b> data file <br/><br/>
71
 * </li>
72
 * 
73
 * <li>
74
 * <h3>Query & Authenticated Query:</h3> 
75
 * Metacat's equivalent is squery action but this function 
76
 * receives a Earthgrid query document and returns Earthgrid resultset document by transforming those documents
77
 * to Metacat's equivalents by the means of Metacat Implementation in Earthgrid library. For authenticated Query service 
78
 * a session id must be provided in the query string. See Earthgrid (a.k.a. Ecogrid) project for XSD files of 
79
 * query and resultset documents<br/><br/>
80
 * 
81
 * <b>REST URL:</b>	<code>POST, [context-root]/object?sessionid=[sessionid]</code>    <br/>
82
 * <b>POST Data:</b> Earthgrid query document , Content-type: <code>text/xml</code><br/>
83
 * <b>Returns:</b> Earthgrid resultset document<br/><br/>
84
 * 
85
 * </li>
86
 * </ul>
87
 * 
88
 * </li>
89
 * 
90
 * <li>
91
 * <h3> EarthGrid Authentication Service</h3>
92
 * <ul><li>
93
 * <h3>Login: </h3> 
94
 * Receives username and password parameters in POST data and 
95
 * returns SessionId (in XML format) or failure message and uses MetacatHandler's handleLoginAction function<br/><br/>
96
 *  
97
 * <b>REST URL:</b> <code>POST, [context-root]/session?op=login</code> <br/>
98
 * <b>POST Data:</b> username=[username]&password=[password], Content-type: <code>application/x-www-form-urlencoded</code>
99
 * <b>Returns:</b> sessionId in XML format<br/><br/>
100
 * </li>
101
 * 
102
 * <li>
103
 * <h3>Logout: </h3> 
104
 * Receives session Id parameters in querystring and returns xml message, calls 
105
 * MetacatHandler's handleLogoutAction function<br/><br/>
106
 *  
107
 * <b>REST URL:</b>	<code>GET, [context-root]/session?op=logout&sessionid=[sessionid]</code>   <br/>
108
 * <b>Returns:</b> message in XML format<br/><br/>
109
 * </li>
110
 * </ul>
111
 * 
112
 * <li>
113
 * <h3>EarthGrid Put Service</h3>
114
 * 
115
 * <ul>
116
 * <li><h3>Update/Insert: </h3>		
117
 * <br/>
118
 * <b>REST URL:</b>	<code>PUT, [context-root]/object/[doc-id]?op={update|insert}&sessionid=[sessionid]</code>   <br/>
119
 * <b>POST Data:</b> document object, Content-type: <code>text/xml</code><br/>
120
 * <b>Returns:</b> message in XML format<br/><br/>
121
 * </li>
122
 * 
123
 * <li><h3>Delete: </h3>		
124
 * <br/>
125
 * <b>REST URL:</b>	<code>DELETE, [context-root]/object/[doc-id]?sessionid=[sessionid]</code>   <br/>
126
 * <b>Returns:</b> message in XML format<br/><br/>
127
 * </li>
128

    
129
 * </ul>
130
 * </li>
131
 * 
132
 * <li>
133
 * <h3>EarthGrid Identifier Service</h3><br/>
134
 * 
135
 * <ul>
136
 * <li><h3>isRegistered: </h3>		<br/>
137
 * <b>REST URL:</b>	<code>GET, [context-root]/identifier/[doc-id]?op=isregistered</code>   <br/>
138
 * <b>Returns:</b> message in XML format<br/><br/>
139
 * </li>
140

    
141
 * <li><h3>getAllDocIds:</h3>		<br/>		
142
 * <b>REST URL:</b>	<code>GET, [context-root]/identifier?op=getalldocids</code>   <br/>
143
 * <b>Returns:</b> document id list in XML format<br/><br/>
144
 * </li>
145
 * 
146
 * <li><h3>addLSID Function:</h3> 
147
 * Metacat does not support this function 		<br/>
148
 * <b>REST URL:</b>	<code>PUT, [context-root]/identifier/[doc-id]</code>   <br/>
149
 * <b>Returns:</b> error message in XML format<br/><br/>
150
 * </li>
151
 * 
152
 * <li><h3>getNextRevision:</h3>		<br/>
153
 * <b>REST URL:</b>	<code>GET, [context-root]/identifier/[doc-id]?op=getnextrevision</code>   <br/>
154
 * <b>Returns:</b> message in XML format<br/><br/>
155
 * </li>
156
 * 
157
 * <li><h3>getNextObject:</h3>		<br/>
158
 * <b>REST URL:</b>	<code>GET, [context-root]/identifier?op=getnextobject&scope=[scope]</code>   <br/>
159
 * <b>Returns:</b> message in XML format<br/><br/>
160
 * </li>
161
 * 
162
 * </li>
163
 * </ul>
164
 * 
165
 */
166
public class ResourceHandler {
167

    
168
    /**HTTP Verb GET*/
169
    public static final byte GET = 1;
170
    /**HTTP Verb POST*/
171
    public static final byte POST = 2;
172
    /**HTTP Verb PUT*/
173
    public static final byte PUT = 3;
174
    /**HTTP Verb DELETE*/
175
    public static final byte DELETE = 4;
176

    
177
    /*
178
     * API Resources
179
     */
180
    private static final String RESOURCE_OBJECTS = "object";
181
    private static final String RESOURCE_SESSION = "session";
182
    private static final String RESOURCE_IDENTIFIER = "identifier";
183

    
184
    /*
185
     * API Functions used as URL parameters
186
     */
187
    private static final String FUNCTION_KEYWORD = "op";
188
    private static final String FUNCTION_NAME_LOGIN = "login";
189
    private static final String FUNCTION_NAME_LOGOUT = "logout";
190
    private static final String FUNCTION_NAME_ISREGISTERED = "isregistered";
191
    private static final String FUNCTION_NAME_GETALLDOCS = "getalldocids";
192
    private static final String FUNCTION_NAME_GETNEXTREV = "getnextrevision";
193
    private static final String FUNCTION_NAME_GETNEXTOBJ = "getnextobject";
194
    private static final String FUNCTION_NAME_INSERT = "insert";
195
    private static final String FUNCTION_NAME_UPDATE = "update";
196

    
197
    private ServletContext servletContext;
198
    private Logger logMetacat;
199
    private MetacatHandler handler;
200
    private HttpServletRequest request;
201
    private HttpServletResponse response;
202
    private String username;
203
    private String password;
204
    private String sessionId;
205
    private String[] groupNames;
206

    
207
    private Hashtable<String, String[]> params;
208

    
209
    /**Initializes new instance by setting servlet context,request and response*/
210
    public ResourceHandler(ServletContext servletContext,
211
            HttpServletRequest request, HttpServletResponse response) {
212
        this.servletContext = servletContext;
213
        this.request = request;
214
        this.response = response;
215
    }
216

    
217
    /**
218
     *  copies request parameters to a hashtable which is given as argument to native metacathandler functions  
219
     */
220
    private void initParams() {
221

    
222
        String name = null;
223
        String[] value = null;
224
        Enumeration paramlist = request.getParameterNames();
225
        while (paramlist.hasMoreElements()) {
226
            name = (String) paramlist.nextElement();
227
            value = request.getParameterValues(name);
228
            params.put(name, value);
229
        }
230

    
231
    }
232

    
233
    /**
234
     * 
235
     * Load user details of metacat session from the request 
236
     * 
237
     */
238
    private void loadSessionData() {
239
        SessionData sessionData = RequestUtil.getSessionData(request);
240

    
241
        // TODO: validate the session before allowing these values to be set
242
        username = sessionData.getUserName();
243
        password = sessionData.getPassword();
244
        groupNames = sessionData.getGroupNames();
245
        sessionId = sessionData.getId();
246

    
247
        if (username == null) {
248
            username = "public";
249
        }
250
    }
251

    
252
    /**
253
     * This function is called from REST APU servlet and handles each request to the servlet 
254
     * 
255
     * @param httpVerb (GET, POST, PUT or DELETE)
256
     */
257
    public void handle(byte httpVerb) {
258

    
259
        logMetacat = Logger.getLogger(ResourceHandler.class);
260
        try {
261
            String resource = request.getServletPath();
262

    
263
            boolean status = false;
264

    
265
            if (resource != null) {
266
                resource = request.getServletPath().substring(1);
267
                System.out.println("accessing resource: " + resource);
268

    
269
                params = new Hashtable<String, String[]>();
270
                initParams();
271

    
272
                Timer timer = new Timer();
273
                handler = new MetacatHandler(servletContext, timer);
274

    
275
                if (resource.equals(RESOURCE_SESSION) && httpVerb == POST
276
                        && params.get(FUNCTION_KEYWORD) != null) {
277
                    if (params.get(FUNCTION_KEYWORD)[0]
278
                            .equals(FUNCTION_NAME_LOGIN)) {
279
                        login();
280
                        status = true;
281
                    } else if (params.get(FUNCTION_KEYWORD)[0]
282
                            .equals(FUNCTION_NAME_LOGOUT)) {
283
                        logout();
284
                        status = true;
285
                    }
286
                } else if (resource.equals(RESOURCE_OBJECTS)) {
287

    
288
                    loadSessionData();
289

    
290
                    String objectId = request.getPathInfo();
291
                    if (objectId != null && objectId.length() > 1)
292
                        objectId = request.getPathInfo().substring(1); //trim the slash
293

    
294
                    System.out.println("verb:" + httpVerb);
295

    
296
                    System.out.println("objectId:" + objectId);
297

    
298
                    if (httpVerb == GET) {
299
                        getObject(objectId);
300
                        status = true;
301
                    } else if (httpVerb == POST) {
302
                        query();
303
                        status = true;
304
                    } else if (httpVerb == PUT) {
305
                        putObject(objectId);
306
                        status = true;
307
                    } else if (httpVerb == DELETE) {
308
                        deleteObject(objectId);
309
                        status = true;
310
                    }
311

    
312
                } else if (resource.equals(RESOURCE_IDENTIFIER)) {
313

    
314
                    String identifierId = request.getPathInfo();
315
                    if (identifierId != null && identifierId.length() > 1)
316
                        identifierId = request.getPathInfo().substring(1); //trim the slash
317

    
318
                    System.out.println("identifierId:" + identifierId);
319

    
320
                    if (httpVerb == GET) {
321
                        String op = params.get(FUNCTION_KEYWORD)[0];
322
                        System.out.println("op:" + op);
323
                        if (op.equals(FUNCTION_NAME_ISREGISTERED)) {
324
                            isRegistered(identifierId);
325
                            status = true;
326
                        } else if (op.equals(FUNCTION_NAME_GETALLDOCS)) {
327
                            getAllDocIds();
328
                            status = true;
329
                        } else if (op.equals(FUNCTION_NAME_GETNEXTREV)) {
330
                            getNextRevision(identifierId);
331
                            status = true;
332
                        } else if (op.equals(FUNCTION_NAME_GETNEXTOBJ)) {
333
                            getNextObject();
334
                            status = true;
335
                        }
336

    
337
                    } else if (httpVerb == PUT) {
338
                        //Earthgrid API > Identifier Service > addLSID Function 
339
                        printError(
340
                                "This method is not supported by metacat.  To "
341
                                        + "add a new LSID, add a document to metacat.",
342
                                response);
343
                        status = true;
344
                    }
345

    
346
                }
347
                if (!status)
348
                    printError("Incorrect parameters!", response);
349
            } else {
350
                printError("Incorrect resource!", response);
351
            }
352
        } catch (Exception e) {
353
            logMetacat.error(e.getMessage());
354
            e.printStackTrace();
355
        }
356
    }
357

    
358
    /**
359
     *  Earthgrid API > Identifier Service > isRegistered Function : calls MetacatHandler > handleIdIsRegisteredAction
360
     * @param guid
361
     * @throws IOException
362
     */
363
    private void isRegistered(String guid) throws IOException
364
    {
365
        
366
        // Look up the localId for this guid
367
        IdentifierManager im = IdentifierManager.getInstance();
368
        String localId = "";
369
        try {
370
            localId = im.getLocalId(guid);
371
        } catch (McdbDocNotFoundException e) {
372
            // TODO: Need to return the proper DataONE exception
373
        }
374
        
375
        params.put("docid", new String[] { localId });
376
        PrintWriter out = response.getWriter();
377
        handler.handleIdIsRegisteredAction(out, params, response);
378
        out.close();
379
    }
380

    
381
    /**
382
     * Earthgrid API > Identifier Service > getAllDocIds Function : calls MetacatHandler > handleGetAllDocidsAction
383
     * @throws IOException
384
     */
385
    private void getAllDocIds() throws IOException {
386
        PrintWriter out = response.getWriter();
387
        handler.handleGetAllDocidsAction(out, params, response);
388
        out.close();
389
    }
390

    
391
    /**
392
     * Earthgrid API > Identifier Service > getNextRevision Function : calls MetacatHandler > handleGetRevisionAndDocTypeAction
393
     * @param guid
394
     * @throws IOException
395
     */
396
    private void getNextRevision(String guid) throws IOException 
397
    {
398
        params.put("docid", new String[] { guid });
399
        PrintWriter out = response.getWriter();
400
        //handler.handleGetRevisionAndDocTypeAction(out, params);
401

    
402
        try {
403
            // Make sure there is a docid
404
            if (guid == null || guid.equals("")) {
405
                throw new Exception("User didn't specify docid!");
406
            }
407

    
408
            // Look up the localId for this guid
409
            IdentifierManager im = IdentifierManager.getInstance();
410
            String localId = "";
411
            try {
412
                localId = im.getLocalId(guid);
413
            } catch (McdbDocNotFoundException e) {
414
                // TODO: Need to return the proper DataONE exception
415
            }
416
           
417
            // Create a DBUtil object
418
            DBUtil dbutil = new DBUtil();
419
            // Get a rev and doctype
420
            String revAndDocType = dbutil
421
                    .getCurrentRevisionAndDocTypeForGivenDocument(localId);
422
            int revision = Integer.parseInt(revAndDocType.split(";")[0]) + 1;
423

    
424
            out.println("<?xml version=\"1.0\"?>");
425
            out.print("<next-revision>");
426
            out.print(revision);
427
            out.print("</next-revision>");
428

    
429
        } catch (Exception e) {
430
            // Handle exception
431
            out.println("<?xml version=\"1.0\"?>");
432
            out.println("<error>");
433
            out.println(e.getMessage());
434
            out.println("</error>");
435
        }
436

    
437
        out.close();
438
    }
439

    
440
    /**
441
     * Earthgrid API > Identifier Service > getNextObject Function : calls MetacatHandler > handleGetMaxDocidAction
442
     * @throws IOException
443
     */
444
    private void getNextObject() throws IOException {
445
        PrintWriter out = response.getWriter();
446
        handler.handleGetMaxDocidAction(out, params, response);
447
        out.close();
448
    }
449

    
450
    /**
451
     * Implements REST version of DataONE CRUD API --> get
452
     * @param guid ID of data object to be read
453
     */
454
    private void getObject(String guid) {
455
        CrudService cs = new CrudService(servletContext, request, response);
456
        AuthToken token = null;
457
        try {
458
            InputStream data = cs.get(token, new IdentifierType(guid));
459
            IOUtils.copyLarge(data, response.getOutputStream());
460
        } catch (BaseException e) {
461
            try {
462
                // TODO: Use content negotiation to determine which return format to use
463
                IOUtils.write(e.serialize(BaseException.FMT_XML), 
464
                        response.getOutputStream());
465
            } catch (IOException e1) {
466
                logMetacat.error("Error writing service exception to stream. " 
467
                        + e1.getMessage());
468
            }
469
        } catch (IOException e) {
470
            ServiceFailure sf = new ServiceFailure(1030, e.getMessage());
471
            try {
472
                IOUtils.write(sf.serialize(BaseException.FMT_XML), 
473
                        response.getOutputStream());
474
            } catch (IOException e1) {
475
                logMetacat.error("Error writing service exception to stream. " 
476
                        + e1.getMessage());
477
            }
478
        }
479
    }
480

    
481
    /**
482
     * Earthgrid API > Query Service > Query Function : translates ecogrid query document to metacat query 
483
     * then calls DBQuery > createResultDocument function and then again translate resultset to ecogrid resultset
484
     * 
485
     * NOTE:
486
     *      This is the only method that uses EcoGrid classes for its implementation.  
487
     *      It does so because it takes an EcoGrid Query as input, and outputs an
488
     *      EcoGrid ResultSet document.  These documents are parsed by the auto-generated
489
     *      EcoGrid classes from axis, and so we link to them here rather than re-inventing them.
490
     *      This creates a circular dependency, because the Metacat classes are needed
491
     *      to build the EcoGrid implementation, and the EcoGrid jars are needed to build this query()
492
     *      method.  This circularity could be resolved by moving the EcoGrid classes
493
     *      to Metacat directly.  As we transition away from EcoGrid SOAP methods in
494
     *      favor of these REST interfaces, this circular dependency can be eliminated.
495
     *        
496
     * @throws Exception
497
     */
498
    private void query() throws Exception {
499
        /*  This block commented out because of the EcoGrid circular dependency.
500
         *  For now, query will not be supported until the circularity can be
501
         *  resolved, probably by moving the ecogrid query syntax transformers
502
         *  directly into the Metacat codebase.  MBJ 2010-02-03
503
         
504
        try {
505
            EcogridQueryParser parser = new EcogridQueryParser(request
506
                    .getReader());
507
            parser.parseXML();
508
            QueryType queryType = parser.getEcogridQuery();
509
            EcogridJavaToMetacatJavaQueryTransformer queryTransformer = 
510
                new EcogridJavaToMetacatJavaQueryTransformer();
511
            QuerySpecification metacatQuery = queryTransformer
512
                    .transform(queryType);
513

    
514
            DBQuery metacat = new DBQuery();
515

    
516
            boolean useXMLIndex = (new Boolean(PropertyService
517
                    .getProperty("database.usexmlindex"))).booleanValue();
518
            String xmlquery = "query"; // we don't care the query in resultset,
519
            // the query can be anything
520
            PrintWriter out = null; // we don't want metacat result, so set out null
521

    
522
            // parameter: queryspecification, user, group, usingIndexOrNot
523
            StringBuffer result = metacat.createResultDocument(xmlquery,
524
                    metacatQuery, out, username, groupNames, useXMLIndex);
525

    
526
            // create result set transfer		
527
            String saxparser = PropertyService.getProperty("xml.saxparser");
528
            MetacatResultsetParser metacatResultsetParser = new MetacatResultsetParser(
529
                    new StringReader(result.toString()), saxparser, queryType
530
                            .getNamespace().get_value());
531
            ResultsetType records = metacatResultsetParser.getEcogridResult();
532

    
533
            System.out
534
                    .println(EcogridResultsetTransformer.toXMLString(records));
535
            response.setContentType("text/xml");
536
            out = response.getWriter();
537
            out.print(EcogridResultsetTransformer.toXMLString(records));
538

    
539
        } catch (Exception e) {
540
            e.printStackTrace();
541
        }*/
542
        response.setContentType("text/xml");
543
        PrintWriter out = response.getWriter();
544
        out.print("<error>Query operation not yet supported by Metacat.</error>");
545
        out.close();
546
    }
547

    
548
    /**
549
     * Earthgrid API > Put Service >Put Function : calls MetacatHandler > handleInsertOrUpdateAction 
550
     * 
551
     * @param objectId ID of data object to be inserted or updated
552
     * @throws IOException
553
     */
554
    private void putObject(String objectId) throws IOException {
555

    
556
        // TODO: This function lacks proper handling of authz and authn, so it
557
        // seems that anyone can insert or update; interacts with 
558
        // loadSessinData(), which doesn't validate the session
559
        
560
        String action = request.getParameter(FUNCTION_KEYWORD);
561

    
562
        if (action.equals(FUNCTION_NAME_UPDATE)
563
                || action.equals(FUNCTION_NAME_INSERT)) {
564
            
565
            // Check if the objectId exists
566
            IdentifierManager im = IdentifierManager.getInstance();
567
            if (im.identifierExists(objectId)) {
568
                // TODO: return IdentifierNotUnique exception
569
            }
570
            
571
            // TODO: For updates, need to check if the old id exists, and if not throw an exception
572
            
573
            // WARNING: This should not be a Reader if we are inserting data
574
            // Nor should it be read into a String
575
            // so this seems like a latent bug to me (MBJ; 16Mar2010)
576
            BufferedReader reader = request.getReader();
577
            StringBuffer buffer = new StringBuffer();
578
            String line = null;
579
            while ((line = reader.readLine()) != null) {
580
                buffer.append(line);
581
            }
582

    
583
            String localId = im.generateLocalId(objectId, 1);
584
            params.put("docid", new String[] { localId });
585
            params.put("doctext", new String[] { buffer.toString().trim() });
586
            params.put("action", new String[] { action });
587

    
588
            if (username != null && !username.equals("public")) {
589
                PrintWriter out = response.getWriter();
590
                handler.handleInsertOrUpdateAction(request, response, out,
591
                        params, username, groupNames);
592
                out.close();
593
            } else {
594
                // TODO: throw exception to show lack of credentials
595
                printError("Permission denied for user " + username, response);
596

    
597
            }
598
        } else {
599
            // TODO: throw the proper exception to indicate an invalid request
600
            printError("Specifiy the operation type.(update or insert)",
601
                    response);
602
        }
603

    
604
    }
605

    
606
    /**
607
     * Earthgrid API > Put Service > Delete Function : calls MetacatHandler > handleDeleteAction  
608
     * 
609
     * @param guid ID of data object to be deleted
610
     * @throws IOException
611
     */
612
    private void deleteObject(String guid) throws IOException 
613
    {
614
        // Look up the localId for this global identifier
615
        IdentifierManager im = IdentifierManager.getInstance();
616
        String localId = "";
617
        try {
618
            localId = im.getLocalId(guid);
619
        } catch (McdbDocNotFoundException e) {
620
            // TODO: Need to return the proper DataONE exception
621
        }
622
        
623
        params.put("docid", new String[] { localId });
624
        PrintWriter out = response.getWriter();
625
        handler.handleDeleteAction(out, params, request, response, username,
626
                groupNames);
627
        out.close();
628
    }
629

    
630
    /**
631
     * Earthgrid API > Authentication Service > Login Function : calls MetacatHandler > handleLoginAction
632
     * 
633
     * @throws IOException
634
     */
635
    private void login() throws IOException {
636
        PrintWriter out = response.getWriter();
637
        handler.handleLoginAction(out, params, request, response);
638
        out.close();
639
    }
640

    
641
    /**
642
     * Earthgrid API > Authentication Service > Logout Function : calls MetacatHandler > handleLogoutAction
643
     * 
644
     * @throws IOException
645
     */
646
    private void logout() throws IOException {
647
        PrintWriter out = response.getWriter();
648
        handler.handleLogoutAction(out, params, request, response);
649
        out.close();
650
    }
651

    
652
    /**
653
     * Prints xml response
654
     * @param message Message to be displayed
655
     * @param response Servlet response that xml message will be printed 
656
     * */
657
    private void printError(String message, HttpServletResponse response) {
658
        try {
659
            PrintWriter out = response.getWriter();
660
            response.setContentType("text/xml");
661
            out.println("<?xml version=\"1.0\"?>");
662
            out.println("<error>");
663
            out.println(message);
664
            out.println("</error>");
665
            out.close();
666
        } catch (IOException e) {
667
            e.printStackTrace();
668
        }
669
    }
670

    
671
}
(1-1/2)