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.Log;
66
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
67
/**
68
 * 
69
 * Base class for handling D1 REST calls in Metacat
70
 * 
71
 * @author leinfelder
72
 */
73
public class D1ResourceHandler {
74

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

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

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

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

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

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

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

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

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

    
146
        } catch (Exception e) {
147
        	// TODO: more D1 structure when failing here
148
        	response.setStatus(400);
149
            printError("Incorrect resource!", response);
150
            logMetacat.error(e.getClass() + ": " + e.getMessage(), e);
151
        }
152
    }
153
    
154
    protected String parseTrailing(String resource, String token) {
155
    	// get the rest
156
        String extra = null;
157
        if (resource.indexOf(token) != -1) {
158
        	// what comes after the token?
159
            extra = resource.substring(resource.indexOf(token) + token.length());
160
            // remove the slash
161
            if (extra.startsWith("/")) {
162
            	extra = extra.substring(1);
163
            }
164
            // is there anything left?
165
            if (extra.length() == 0) {
166
            	extra = null;
167
            }
168
        }
169
        return extra;
170
    }
171

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

    
194
        // Read the incoming data from its Mime Multipart encoding
195
        logMetacat.debug("Parsing BaseException from the mime multipart entity");
196

    
197
        // handle MMP inputs
198
        MultipartRequestResolver mrr = 
199
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
200

    
201
        try {
202
            mr = mrr.resolveMultipart(request);
203
            logMetacat.debug("Resolved the replication status BaseException multipart request.");
204
            
205
        } catch (IOException e) {
206
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
207
                e.getMessage());
208
            
209
        } catch (FileUploadException e) {
210
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
211
                e.getMessage());
212
            
213
        } catch (Exception e) {
214
            throw new ServiceFailure("4700", "Couldn't resolve the multipart request: " +
215
                e.getMessage());
216
            
217
        }
218

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

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

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

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

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

    
455
		multipartparams = mr.getMultipartParameters();
456

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

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

    
497
		if (files.keySet() == null) {
498
			logMetacat.error("No file keys in MMP request.");
499
			throw new ServiceFailure(
500
					"1202",
501
					"No file keys found in MMP.  "
502
							+ "register meta must have multipart file with name 'sysmeta'");
503
		}
504

    
505
		// for logging purposes, dump out the key-value pairs that
506
		// constitute the request
507
		// 3 types exist: request params, multipart params, and
508
		// multipart files
509
		Iterator it = files.keySet().iterator();
510
		logMetacat.debug("iterating through request parts: " + it);
511
		while (it.hasNext()) {
512
			String key = (String) it.next();
513
			logMetacat.debug("files key: " + key);
514
			logMetacat.debug("files value: " + files.get(key));
515
		}
516

    
517
		multipartparams = mr.getMultipartParameters();
518
		it = multipartparams.keySet().iterator();
519
		while (it.hasNext()) {
520
			String key = (String) it.next();
521
			logMetacat.debug("multipartparams key: " + key);
522
			logMetacat.debug("multipartparams value: " + multipartparams.get(key));
523
		}
524

    
525
		it = params.keySet().iterator();
526
		while (it.hasNext()) {
527
			String key = (String) it.next();
528
			logMetacat.debug("param key: " + key);
529
			logMetacat.debug("param value: " + params.get(key));
530
		}
531
		logMetacat.debug("done iterating the request...");
532

    
533
		File smFile = files.get("sysmeta");
534
		if (smFile == null) {
535
			throw new InvalidRequest("1102",
536
					"Missing the required file-part 'sysmeta' from the multipart request.");
537
		}
538
		logMetacat.debug("smFile: " + smFile.getAbsolutePath());
539
		sysmeta = new FileInputStream(smFile);
540
	
541
		logMetacat.debug("Commence creation...");
542
		SystemMetadata systemMetadata = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class, sysmeta);
543
		return systemMetadata;
544
	}
545
    
546
    protected Map<String, File> collectMultipartFiles() 
547
        throws ServiceFailure, InvalidRequest {
548
    	
549
        // Read the incoming data from its Mime Multipart encoding
550
        logMetacat.debug("Disassembling MIME multipart form");
551
        InputStream object = null;
552
        InputStream sysmeta = null;
553
        
554
        
555
        // handle MMP inputs
556
        File tmpDir = getTempDirectory();
557
        logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
558
        MultipartRequestResolver mrr = 
559
        	new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
560
        MultipartRequest mr = null;
561
		try {
562
			mr = mrr.resolveMultipart(request);
563
		} catch (Exception e) {
564
            throw new ServiceFailure("1202", 
565
            		"Could not resolve multipart files: " + e.getMessage());
566
		}
567
        logMetacat.debug("resolved multipart request");
568
        Map<String, File> files = mr.getMultipartFiles();
569
        if (files == null) {
570
            throw new ServiceFailure("1202", "create/update must have multipart files with names 'object' and 'sysmeta'");
571
        }
572
        logMetacat.debug("got multipart files");
573
        
574
        if (files.keySet() == null) {
575
            logMetacat.error("No file keys in MMP request.");
576
            throw new ServiceFailure("1202", "No file keys found in MMP.  " +
577
                    "create/update must have multipart files with names 'object' and 'sysmeta'");
578
        }
579

    
580
		// for logging purposes, dump out the key-value pairs that constitute the request
581
		// 3 types exist: request params, multipart params, and multipart files
582
        Iterator it = files.keySet().iterator();
583
        logMetacat.debug("iterating through files");
584
        while (it.hasNext()) {
585
            String key = (String)it.next();
586
            logMetacat.debug("files key: " + key);
587
            logMetacat.debug("files value: " + files.get(key));
588
        }
589
        
590
        multipartparams = mr.getMultipartParameters();
591
        it = multipartparams.keySet().iterator();
592
        logMetacat.debug("iterating through multipartparams");
593
        while (it.hasNext()) {
594
            String key = (String)it.next();
595
            logMetacat.debug("multipartparams key: " + key);
596
            logMetacat.debug("multipartparams value: " + multipartparams.get(key));
597
        }
598
        
599
        it = params.keySet().iterator();
600
        logMetacat.debug("iterating through params");
601
        while (it.hasNext()) {
602
            String key = (String)it.next();
603
            logMetacat.debug("param key: " + key);
604
            logMetacat.debug("param value: " + params.get(key));
605
        }
606
        logMetacat.debug("done iterating the request...");
607

    
608
        File smFile = files.get("sysmeta");
609
		if (smFile == null) {
610
		    throw new InvalidRequest("1102", "Missing the required file-part 'sysmeta' from the multipart request.");
611
		}
612
        logMetacat.debug("smFile: " + smFile.getAbsolutePath());
613
        File objFile = files.get("object");
614
		if (objFile == null) {
615
		    throw new InvalidRequest("1102", "Missing the required file-part 'object' from the multipart request.");
616
		}
617
        logMetacat.debug("objectfile: " + objFile.getAbsolutePath());
618
        
619
        return files;
620
    }
621
    
622
		/**
623
     *  copies request parameters to a hashtable which is given as argument to 
624
     *  native metacathandler functions  
625
     */
626
    protected void initParams() {
627

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

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

    
765
}
(4-4/9)