Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2011 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.File;
26
import java.io.FileInputStream;
27
import java.io.FileNotFoundException;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.io.OutputStream;
31
import java.io.PrintWriter;
32
import java.util.Enumeration;
33
import java.util.Hashtable;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Map;
37
import java.util.Timer;
38

    
39
import javax.servlet.ServletContext;
40
import javax.servlet.http.HttpServletRequest;
41
import javax.servlet.http.HttpServletResponse;
42
import javax.xml.parsers.ParserConfigurationException;
43

    
44
import org.apache.commons.fileupload.FileUploadException;
45
import org.apache.commons.io.IOUtils;
46
import org.apache.log4j.Logger;
47
import org.dataone.client.auth.CertificateManager;
48
import org.dataone.mimemultipart.MultipartRequest;
49
import org.dataone.mimemultipart.MultipartRequestResolver;
50
import org.dataone.service.exceptions.BaseException;
51
import org.dataone.service.exceptions.InvalidRequest;
52
import org.dataone.service.exceptions.ServiceFailure;
53
import org.dataone.service.types.v1.AccessPolicy;
54
import org.dataone.service.types.v1.Replica;
55
import org.dataone.service.types.v1.ReplicationPolicy;
56
import org.dataone.service.types.v1.Session;
57
import org.dataone.service.types.v1.SystemMetadata;
58
import org.dataone.service.util.ExceptionHandler;
59
import org.dataone.service.util.TypeMarshaller;
60
import org.jibx.runtime.JiBXException;
61
import org.xml.sax.SAXException;
62

    
63
import edu.ucsb.nceas.metacat.MetacatHandler;
64
import edu.ucsb.nceas.metacat.properties.PropertyService;
65
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
66
/**
67
 * 
68
 * Base class for handling D1 REST calls in Metacat
69
 * 
70
 * @author leinfelder
71
 */
72
public class D1ResourceHandler {
73

    
74
    /**HTTP Verb GET*/
75
    public static final byte GET = 1;
76
    /**HTTP Verb POST*/
77
    public static final byte POST = 2;
78
    /**HTTP Verb PUT*/
79
    public static final byte PUT = 3;
80
    /**HTTP Verb DELETE*/
81
    public static final byte DELETE = 4;
82
    /**HTTP Verb HEAD*/
83
    public static final byte HEAD = 5;
84

    
85
    /*
86
     * API Resources
87
     */
88
    protected static final String RESOURCE_BASE_URL = "d1";
89

    
90
    protected static final String RESOURCE_OBJECTS = "object";
91
    protected static final String RESOURCE_META = "meta";
92
    protected static final String RESOURCE_LOG = "log";
93
    protected static final String RESOURCE_CHECKSUM = "checksum";
94
    
95
    protected static final String RESOURCE_IS_AUTHORIZED = "isAuthorized";
96
    protected static final String RESOURCE_ACCESS_RULES = "accessRules";
97

    
98
    
99
    /*
100
     * API Functions used as URL parameters
101
     */
102
    protected static final String FUNCTION_NAME_INSERT = "insert";
103
    protected static final String FUNCTION_NAME_UPDATE = "update";
104
    
105
    protected ServletContext servletContext;
106
    protected Logger logMetacat;
107
    protected MetacatHandler handler;
108
    protected HttpServletRequest request;
109
    protected HttpServletResponse response;
110

    
111
    protected Hashtable<String, String[]> params;
112
    protected Map<String, List<String>> multipartparams;
113
    
114
    // D1 certificate-based authentication
115
    protected Session session;
116

    
117
    /**Initializes new instance by setting servlet context,request and response*/
118
    public D1ResourceHandler(ServletContext servletContext,
119
            HttpServletRequest request, HttpServletResponse response) {
120
        this.servletContext = servletContext;
121
        this.request = request;
122
        this.response = response;
123
    }
124

    
125
    /**
126
     * This function is called from REST API servlet and handles each request 
127
     * 
128
     * @param httpVerb (GET, POST, PUT or DELETE)
129
     */
130
    public void handle(byte httpVerb) {
131
        logMetacat = Logger.getLogger(D1ResourceHandler.class);
132
        try {
133
  
134
            // load session from certificate in request
135
            session = CertificateManager.getInstance().getSession(request);
136

    
137
            // initialize the parameters
138
            params = new Hashtable<String, String[]>();
139
            initParams();
140

    
141
            // create the handler for interacting with Metacat
142
            Timer timer = new Timer();
143
            handler = new MetacatHandler(timer);
144

    
145
        } catch (Exception e) {
146
        	// TODO: more D1 structure when failing here
147
        	response.setStatus(400);
148
            printError("Incorrect resource!", response);
149
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
150
        }
151
    }
152

    
153
    /**
154
     * subclasses should provide a more useful implementation
155
     * @return
156
     */
157
    protected boolean isD1Enabled() {
158
    	
159
    	return true;	
160
    }
161
    
162
    protected String parseTrailing(String resource, String token) {
163
    	// get the rest
164
        String extra = null;
165
        if (resource.indexOf(token) != -1) {
166
        	// what comes after the token?
167
            extra = resource.substring(resource.indexOf(token) + token.length());
168
            // remove the slash
169
            if (extra.startsWith("/")) {
170
            	extra = extra.substring(1);
171
            }
172
            // is there anything left?
173
            if (extra.length() == 0) {
174
            	extra = null;
175
            }
176
        }
177
        return extra;
178
    }
179

    
180
    /**
181
     * Parse the BaseException information for replication status failures if any
182
     * 
183
     * @return failure  the BaseException failure, one of it's subclasses, or null
184
     * @throws ServiceFailure
185
     * @throws InvalidRequest
186
     * @throws JiBXException 
187
     * @throws IllegalAccessException 
188
     * @throws InstantiationException 
189
     * @throws IOException 
190
     */
191
    protected BaseException collectReplicationStatus() 
192
        throws ServiceFailure, InvalidRequest, IOException, 
193
        InstantiationException, IllegalAccessException, JiBXException {
194
        
195
        BaseException failure = null;
196
        File tmpDir = getTempDirectory();
197
        MultipartRequest mr = null;
198
        Map<String, File> mmFileParts = null;
199
        File exceptionFile = null;
200
        InputStream exceptionFileStream = null;
201

    
202
        // Read the incoming data from its Mime Multipart encoding
203
        logMetacat.debug("Parsing BaseException from the mime multipart entity");
204

    
205
        // handle MMP inputs
206
        MultipartRequestResolver mrr = 
207
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
208

    
209
        try {
210
            mr = mrr.resolveMultipart(request);
211
            logMetacat.debug("Resolved the replication status BaseException multipart request.");
212
            
213
        } catch (IOException e) {
214
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
215
                e.getMessage());
216
            
217
        } catch (FileUploadException e) {
218
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
219
                e.getMessage());
220
            
221
        } catch (Exception e) {
222
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
223
                e.getMessage());
224
            
225
        }
226

    
227
        // get the map of file parts
228
        mmFileParts = mr.getMultipartFiles();
229
        
230
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
231
            logMetacat.debug("BaseException for setReplicationStatus is null");            
232
        }
233
        
234
        multipartparams = mr.getMultipartParameters();
235
        exceptionFile = mmFileParts.get("failure");
236
        
237
        if ( exceptionFile != null ) {
238
            
239
            // deserialize the BaseException subclass
240
            exceptionFileStream = new FileInputStream(exceptionFile);
241
            try {
242
                failure = ExceptionHandler.deserializeXml(exceptionFileStream, 
243
                    "Replication failed for an unknown reason.");
244
                
245
            } catch (ParserConfigurationException e) {
246
                throw new ServiceFailure("4700", "Couldn't parse the replication failure exception: " +
247
                        e.getMessage());
248
                
249
            } catch (SAXException e) {
250
                throw new ServiceFailure("4700", "Couldn't traverse the replication failure exception: " +
251
                        e.getMessage());
252
                
253
            }
254
                
255
        }
256
        
257
        
258
        return failure;
259
        
260
    }
261
    
262
    /**
263
     * Parse the replication policy document out of the mime-multipart form data
264
     * 
265
     * @return policy  the encoded policy
266
     * @throws ServiceFailure
267
     * @throws InvalidRequest
268
     * @throws IOException
269
     * @throws InstantiationException
270
     * @throws IllegalAccessException
271
     * @throws JiBXException
272
     */
273
    protected ReplicationPolicy collectReplicationPolicy() 
274
        throws ServiceFailure, InvalidRequest, IOException, InstantiationException, 
275
        IllegalAccessException, JiBXException {
276
        
277
        ReplicationPolicy policy = null;
278
        File tmpDir = getTempDirectory();
279
        MultipartRequest mr = null;
280
        Map<String, File> mmFileParts = null;
281
        File replPolicyFile = null;
282
        InputStream replPolicyStream = null;
283
        
284
        // Read the incoming data from its Mime Multipart encoding
285
        logMetacat.debug("Parsing ReplicationPolicy from the mime multipart entity");
286

    
287
        // handle MMP inputs
288
        MultipartRequestResolver mrr = 
289
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
290
        
291
        try {
292
            mr = mrr.resolveMultipart(request);
293
            logMetacat.debug("Resolved the ReplicationPolicy multipart request.");
294
            
295
        } catch (IOException e) {
296
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
297
                e.getMessage());
298
            
299
        } catch (FileUploadException e) {
300
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
301
                e.getMessage());
302
            
303
        } catch (Exception e) {
304
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
305
                e.getMessage());
306
            
307
        }
308
        
309
        // get the map of file parts
310
        mmFileParts = mr.getMultipartFiles();
311
        
312
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
313
            throw new InvalidRequest("4883", "The multipart request must include " +
314
                "a file with the name 'policy'.");
315
            
316
        }
317
        
318
        multipartparams = mr.getMultipartParameters();
319
        replPolicyFile = mmFileParts.get("policy");
320
        
321
        if ( replPolicyFile == null ) {
322
            throw new InvalidRequest("4883", "The multipart request must include " +
323
            "a file with the name 'policy'.");
324
            
325
        }
326
        
327
        
328
        // deserialize the ReplicationPolicy
329
        replPolicyStream = new FileInputStream(replPolicyFile);
330
        policy = TypeMarshaller.unmarshalTypeFromStream(ReplicationPolicy.class, replPolicyStream);
331
        
332
        return policy;
333
        
334
    }
335

    
336
    /**
337
     * Parse the replica metadata document out of the mime-multipart form data
338
     * 
339
     * @return replica  the encoded replica
340
     * @throws ServiceFailure
341
     * @throws InvalidRequest
342
     * @throws IOException
343
     * @throws InstantiationException
344
     * @throws IllegalAccessException
345
     * @throws JiBXException
346
     */
347
    protected Replica collectReplicaMetadata() 
348
        throws ServiceFailure, InvalidRequest {
349
        
350
        Replica replica = null;
351
        File tmpDir = getTempDirectory();
352
        MultipartRequest mr = null;
353
        Map<String, File> mmFileParts = null;
354
        File replicaFile = null;
355
        InputStream replicaStream = null;
356
        
357
        // Read the incoming data from its Mime Multipart encoding
358
        logMetacat.debug("Parsing Replica from the mime multipart entity");
359

    
360
        // handle MMP inputs
361
        MultipartRequestResolver mrr = 
362
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
363
        
364
        try {
365
            mr = mrr.resolveMultipart(request);
366
            logMetacat.debug("Resolved the Replica multipart request.");
367
            
368
        } catch (IOException e) {
369
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
370
                e.getMessage());
371
            
372
        } catch (FileUploadException e) {
373
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
374
                    e.getMessage());
375
            
376
        } catch (Exception e) {
377
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
378
                    e.getMessage());
379
            
380
        }
381
        
382
        // get the map of file parts
383
        mmFileParts = mr.getMultipartFiles();
384
        
385
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
386
            throw new InvalidRequest("4853", "The multipart request must include " +
387
                "a file with the name 'replicaMetadata'.");
388
            
389
        }
390
        
391
        multipartparams = mr.getMultipartParameters();
392
        replicaFile = mmFileParts.get("replicaMetadata");
393
        
394
        if ( replicaFile == null ) {
395
            throw new InvalidRequest("4853", "The multipart request must include " +
396
            "a file with the name 'replicaMetadata'.");
397
            
398
        }
399
        
400
        
401
        // deserialize the ReplicationPolicy
402
        try {
403
            replicaStream = new FileInputStream(replicaFile);
404
        } catch (FileNotFoundException e) {
405
            throw new ServiceFailure("4852", "Couldn't find the multipart file: " +
406
                    e.getMessage());
407
            
408
        }
409
        
410
        try {
411
            replica = TypeMarshaller.unmarshalTypeFromStream(Replica.class, replicaStream);
412
        } catch (IOException e) {
413
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
414
                    e.getMessage());
415
            
416
        } catch (InstantiationException e) {
417
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
418
                    e.getMessage());
419
            
420
        } catch (IllegalAccessException e) {
421
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
422
                    e.getMessage());
423
            
424
        } catch (JiBXException e) {
425
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
426
                    e.getMessage());
427
            
428
        }
429
        
430
        return replica;
431
        
432
    }
433
    
434
    protected AccessPolicy collectAccessPolicy() 
435
        throws IOException, ServiceFailure, InvalidRequest, JiBXException, 
436
        InstantiationException, IllegalAccessException, ParserConfigurationException, 
437
        SAXException  {
438
		
439
		// Read the incoming data from its Mime Multipart encoding
440
		logMetacat.debug("Disassembling MIME multipart form");
441
		InputStream ap = null;
442

    
443
		// handle MMP inputs
444
		File tmpDir = getTempDirectory();
445
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
446
		MultipartRequestResolver mrr = 
447
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
448
		MultipartRequest mr = null;
449
		try {
450
			mr = mrr.resolveMultipart(request);
451
		} catch (Exception e) {
452
			throw new ServiceFailure("2161", 
453
					"Could not resolve multipart: " + e.getMessage());
454
		}
455
		logMetacat.debug("resolved multipart request");
456
		Map<String, File> files = mr.getMultipartFiles();
457
		if (files == null || files.keySet() == null) {
458
			throw new InvalidRequest("2163",
459
					"must have multipart file with name 'accessPolicy'");
460
		}
461
		logMetacat.debug("got multipart files");
462

    
463
		multipartparams = mr.getMultipartParameters();
464

    
465
		File apFile = files.get("accessPolicy");
466
		if (apFile == null) {
467
			throw new InvalidRequest("2163",
468
					"Missing the required file-part 'accessPolicy' from the multipart request.");
469
		}
470
		logMetacat.debug("apFile: " + apFile.getAbsolutePath());
471
		ap = new FileInputStream(apFile);
472
	
473
		AccessPolicy accessPolicy = TypeMarshaller.unmarshalTypeFromStream(AccessPolicy.class, ap);
474
		return accessPolicy;
475
	}
476
    
477
    protected SystemMetadata collectSystemMetadata() 
478
        throws IOException, FileUploadException, ServiceFailure, InvalidRequest, 
479
        JiBXException, InstantiationException, IllegalAccessException  {
480
		
481
		// Read the incoming data from its Mime Multipart encoding
482
		logMetacat.debug("Disassembling MIME multipart form");
483
		InputStream sysmeta = null;
484

    
485
		// handle MMP inputs
486
		File tmpDir = getTempDirectory();
487
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
488
		MultipartRequestResolver mrr = 
489
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
490
		MultipartRequest mr = null;
491
		try {
492
			mr = mrr.resolveMultipart(request);
493
		} catch (Exception e) {
494
			throw new ServiceFailure("1202", 
495
					"Could not resolve multipart: " + e.getMessage());
496
		}
497
		logMetacat.debug("resolved multipart request");
498
		Map<String, File> files = mr.getMultipartFiles();
499
		if (files == null) {
500
			throw new ServiceFailure("1202",
501
					"register meta must have multipart file with name 'sysmeta'");
502
		}
503
		logMetacat.debug("got multipart files");
504

    
505
		if (files.keySet() == null) {
506
			logMetacat.error("No file keys in MMP request.");
507
			throw new ServiceFailure(
508
					"1202",
509
					"No file keys found in MMP.  "
510
							+ "register meta must have multipart file with name 'sysmeta'");
511
		}
512

    
513
		// for logging purposes, dump out the key-value pairs that
514
		// constitute the request
515
		// 3 types exist: request params, multipart params, and
516
		// multipart files
517
		Iterator it = files.keySet().iterator();
518
		logMetacat.debug("iterating through request parts: " + it);
519
		while (it.hasNext()) {
520
			String key = (String) it.next();
521
			logMetacat.debug("files key: " + key);
522
			logMetacat.debug("files value: " + files.get(key));
523
		}
524

    
525
		multipartparams = mr.getMultipartParameters();
526
		it = multipartparams.keySet().iterator();
527
		while (it.hasNext()) {
528
			String key = (String) it.next();
529
			logMetacat.debug("multipartparams key: " + key);
530
			logMetacat.debug("multipartparams value: " + multipartparams.get(key));
531
		}
532

    
533
		it = params.keySet().iterator();
534
		while (it.hasNext()) {
535
			String key = (String) it.next();
536
			logMetacat.debug("param key: " + key);
537
			logMetacat.debug("param value: " + params.get(key));
538
		}
539
		logMetacat.debug("done iterating the request...");
540

    
541
		File smFile = files.get("sysmeta");
542
		if (smFile == null) {
543
			throw new InvalidRequest("1102",
544
					"Missing the required file-part 'sysmeta' from the multipart request.");
545
		}
546
		logMetacat.debug("smFile: " + smFile.getAbsolutePath());
547
		sysmeta = new FileInputStream(smFile);
548
	
549
		logMetacat.debug("Commence creation...");
550
		SystemMetadata systemMetadata = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class, sysmeta);
551
		return systemMetadata;
552
	}
553
    
554
    /**
555
     * Process the MMP request that includes files for each param
556
     * @return map of param key and the tem pfile that contains the encoded information
557
     * @throws ServiceFailure
558
     * @throws InvalidRequest
559
     */
560
    protected Map<String, File> collectMultipartFiles() 
561
        throws ServiceFailure, InvalidRequest {
562
    	
563
        // Read the incoming data from its Mime Multipart encoding
564
        logMetacat.debug("Disassembling MIME multipart form");
565
        
566
        // handle MMP inputs
567
        File tmpDir = getTempDirectory();
568
        logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
569
        MultipartRequestResolver mrr = 
570
        	new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
571
        MultipartRequest mr = null;
572
		try {
573
			mr = mrr.resolveMultipart(request);
574
		} catch (Exception e) {
575
            throw new ServiceFailure("1202", 
576
            		"Could not resolve multipart files: " + e.getMessage());
577
		}
578
        logMetacat.debug("resolved multipart request");
579
        Map<String, File> files = mr.getMultipartFiles();
580
        if (files == null) {
581
            throw new ServiceFailure("1202", "no multipart files found");
582
        }
583
        logMetacat.debug("got multipart files");
584
        
585
        if (files.keySet() == null) {
586
            logMetacat.error("No file keys in MMP request.");
587
            throw new ServiceFailure("1202", "No file keys found in MMP.");
588
        }
589
        
590
        multipartparams = mr.getMultipartParameters();
591

    
592
		// for logging purposes, dump out the key-value pairs that constitute the request
593
		// 3 types exist: request params, multipart params, and multipart files
594
        if (logMetacat.isDebugEnabled()) {
595
	        Iterator<String> it = files.keySet().iterator();
596
	        logMetacat.debug("iterating through files");
597
	        while (it.hasNext()) {
598
	            String key = it.next();
599
	            logMetacat.debug("files key: " + key);
600
	            logMetacat.debug("files value: " + files.get(key));
601
	        }
602
	        
603
	        it = multipartparams.keySet().iterator();
604
	        logMetacat.debug("iterating through multipartparams");
605
	        while (it.hasNext()) {
606
	            String key = (String)it.next();
607
	            logMetacat.debug("multipartparams key: " + key);
608
	            logMetacat.debug("multipartparams value: " + multipartparams.get(key));
609
	        }
610
	        
611
	        it = params.keySet().iterator();
612
	        logMetacat.debug("iterating through params");
613
	        while (it.hasNext()) {
614
	            String key = (String)it.next();
615
	            logMetacat.debug("param key: " + key);
616
	            logMetacat.debug("param value: " + params.get(key));
617
	        }
618
	        logMetacat.debug("done iterating the request...");
619
        }
620
        
621
        return files;
622
    }
623
    
624
		/**
625
     *  copies request parameters to a hashtable which is given as argument to 
626
     *  native metacathandler functions  
627
     */
628
    protected void initParams() {
629

    
630
        String name = null;
631
        String[] value = null;
632
        Enumeration paramlist = request.getParameterNames();
633
        while (paramlist.hasMoreElements()) {
634
            name = (String) paramlist.nextElement();
635
            value = request.getParameterValues(name);
636
            params.put(name, value);
637
        }
638
    }
639
    
640
    /**
641
     * Collect the multipart params from the request
642
     * @throws Exception 
643
     */
644
	protected void initMultipartParams() throws Exception {
645
		
646
		// Read the incoming data from its Mime Multipart encoding
647
		logMetacat.debug("Disassembling MIME multipart form");
648
	
649
		// handle MMP inputs
650
		File tmpDir = getTempDirectory();
651
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
652
		MultipartRequestResolver mrr = 
653
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
654
		MultipartRequest mr = mrr.resolveMultipart(request);
655
		
656
		multipartparams = mr.getMultipartParameters();
657
	}
658
   
659
    /**
660
     * locate the boundary marker for an MMP
661
     * @param is
662
     * @return
663
     * @throws IOException
664
     */
665
    protected static String[] findBoundaryString(InputStream is)
666
        throws IOException {
667
        String[] endResult = new String[2];
668
        String boundary = "";
669
        String searchString = "boundary=";
670
        byte[] b = new byte[1024];
671
        int numbytes = is.read(b, 0, 1024);
672

    
673
        while(numbytes != -1)
674
        {
675
            String s = new String(b, 0, numbytes);
676
            int searchStringIndex = s.indexOf(searchString);
677
            
678
            if(s.indexOf("\"", searchStringIndex + searchString.length() + 1) == -1)
679
            { //the end of the boundary is in the next byte array
680
                boundary = s.substring(searchStringIndex + searchString.length() + 1, s.length());
681
            }
682
            else if(!boundary.startsWith("--"))
683
            { //we can read the whole boundary from this byte array
684
                boundary = s.substring(searchStringIndex + searchString.length() + 1, 
685
                    s.indexOf("\"", searchStringIndex + searchString.length() + 1));
686
                boundary = "--" + boundary;
687
                endResult[0] = boundary;
688
                endResult[1] = s.substring(s.indexOf("\"", searchStringIndex + searchString.length() + 1) + 1,
689
                        s.length());
690
                break;
691
            }
692
            else
693
            { //we're now reading the 2nd byte array to get the rest of the boundary
694
                searchString = "\"";
695
                searchStringIndex = s.indexOf(searchString);
696
                boundary += s.substring(0, searchStringIndex);
697
                boundary = "--" + boundary;
698
                endResult[0] = boundary;
699
                endResult[1] = s.substring(s.indexOf("\"", searchStringIndex + searchString.length() + 1) + 1,
700
                        s.length());
701
                break;
702
            }
703
        }
704
        return endResult;
705
    }
706
    
707
    /**
708
     * return the directory where temp files are stored
709
     * @return
710
     */
711
    protected static File getTempDirectory()
712
    {
713
        File tmpDir = null;
714
        Logger logMetacat = Logger.getLogger(D1ResourceHandler.class);
715
        try {
716
            tmpDir = new File(PropertyService.getProperty("application.tempDir"));
717
        }
718
        catch(PropertyNotFoundException pnfe) {
719
            logMetacat.error("D1ResourceHandler.writeMMPPartstoFiles: " +
720
                    "application.tmpDir not found.  Using /tmp instead.");
721
            tmpDir = new File("/tmp");
722
        }
723
        return tmpDir;
724
    }
725
    
726
    /**
727
     * Prints xml response
728
     * @param message Message to be displayed
729
     * @param response Servlet response that xml message will be printed 
730
     * */
731
    protected void printError(String message, HttpServletResponse response) {
732
        try {
733
            logMetacat.error("D1ResourceHandler: Printing error to servlet response: " + message);
734
            PrintWriter out = response.getWriter();
735
            response.setContentType("text/xml");
736
            out.println("<?xml version=\"1.0\"?>");
737
            out.println("<error>");
738
            out.println(message);
739
            out.println("</error>");
740
            out.close();
741
        } catch (IOException e) {
742
            e.printStackTrace();
743
        }
744
    }
745
    
746
    /**
747
     * serialize a D1 exception using jibx
748
     * @param e
749
     * @param out
750
     */
751
    protected void serializeException(BaseException e, OutputStream out) {
752
        // TODO: Use content negotiation to determine which return format to use
753
        response.setContentType("text/xml");
754
        response.setStatus(e.getCode());
755
        
756
        logMetacat.error("D1ResourceHandler: Serializing exception with code " + e.getCode() + ": " + e.getMessage());
757
        e.printStackTrace();
758
        
759
        try {
760
            IOUtils.write(e.serialize(BaseException.FMT_XML), out);
761
        } catch (IOException e1) {
762
            logMetacat.error("Error writing exception to stream. " 
763
                    + e1.getMessage());
764
        }
765
    }
766

    
767
}
(4-4/9)