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
    
94
    protected static final String RESOURCE_IS_AUTHORIZED = "isAuthorized";
95
    protected static final String RESOURCE_ACCESS_RULES = "accessRules";
96

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

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

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

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

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

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

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

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

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

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

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

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

    
226
        // get the map of file parts
227
        mmFileParts = mr.getMultipartFiles();
228
        
229
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
230
            logMetacat.debug("BaseException for setReplicationStatus is null");            
231
        }
232
        
233
        multipartparams = mr.getMultipartParameters();
234
        exceptionFile = mmFileParts.get("failure");
235
        
236
        if ( exceptionFile != null && exceptionFile.length() > 0 ) {
237
            
238
            // deserialize the BaseException subclass
239
            exceptionFileStream = new FileInputStream(exceptionFile);
240
            try {
241
                failure = ExceptionHandler.deserializeXml(exceptionFileStream, 
242
                    "Replication failed for an unknown reason.");
243
                
244
            } catch (ParserConfigurationException e) {
245
                throw new ServiceFailure("4700", "Couldn't parse the replication failure exception: " +
246
                        e.getMessage());
247
                
248
            } catch (SAXException e) {
249
                throw new ServiceFailure("4700", "Couldn't traverse the replication failure exception: " +
250
                        e.getMessage());
251
                
252
            }
253
                
254
        }
255
        
256
        
257
        return failure;
258
        
259
    }
260

    
261
    /**
262
     * Parse string parameters from the mime multipart entity of the request.
263
     * Populates the multipartparams map
264
     * 
265
     * @throws IOException
266
     * @throws FileUploadException
267
     * @throws Exception
268
     */
269
    protected void collectMultipartParams() 
270
        throws IOException, FileUploadException, Exception {
271
        
272
        File tmpDir = getTempDirectory();
273
        MultipartRequest mr = null;
274

    
275
        // Read the incoming data from its Mime Multipart encoding
276
        logMetacat.debug("Parsing rights holder info from the mime multipart entity");
277

    
278
        // handle MMP inputs
279
        MultipartRequestResolver mrr = 
280
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
281

    
282
        mr = mrr.resolveMultipart(request);
283
        logMetacat.debug("Resolved the rights holder info from the mime multipart entity.");
284
                    
285
        // we only have params in this MMP entity
286
        multipartparams = mr.getMultipartParameters();
287
                
288
    }
289
    
290

    
291
    /**
292
     * Parse the replication policy document out of the mime-multipart form data
293
     * 
294
     * @return policy  the encoded policy
295
     * @throws ServiceFailure
296
     * @throws InvalidRequest
297
     * @throws IOException
298
     * @throws InstantiationException
299
     * @throws IllegalAccessException
300
     * @throws JiBXException
301
     */
302
    protected ReplicationPolicy collectReplicationPolicy() 
303
        throws ServiceFailure, InvalidRequest, IOException, InstantiationException, 
304
        IllegalAccessException, JiBXException {
305
        
306
        ReplicationPolicy policy = null;
307
        File tmpDir = getTempDirectory();
308
        MultipartRequest mr = null;
309
        Map<String, File> mmFileParts = null;
310
        File replPolicyFile = null;
311
        InputStream replPolicyStream = null;
312
        
313
        // Read the incoming data from its Mime Multipart encoding
314
        logMetacat.debug("Parsing ReplicationPolicy from the mime multipart entity");
315

    
316
        // handle MMP inputs
317
        MultipartRequestResolver mrr = 
318
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
319
        
320
        try {
321
            mr = mrr.resolveMultipart(request);
322
            logMetacat.debug("Resolved the ReplicationPolicy multipart request.");
323
            
324
        } catch (IOException e) {
325
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
326
                e.getMessage());
327
            
328
        } catch (FileUploadException e) {
329
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
330
                e.getMessage());
331
            
332
        } catch (Exception e) {
333
            throw new ServiceFailure("4882", "Couldn't resolve the multipart request: " +
334
                e.getMessage());
335
            
336
        }
337
        
338
        // get the map of file parts
339
        mmFileParts = mr.getMultipartFiles();
340
        
341
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
342
            throw new InvalidRequest("4883", "The multipart request must include " +
343
                "a file with the name 'policy'.");
344
            
345
        }
346
        
347
        multipartparams = mr.getMultipartParameters();
348
        replPolicyFile = mmFileParts.get("policy");
349
        
350
        if ( replPolicyFile == null ) {
351
            throw new InvalidRequest("4883", "The multipart request must include " +
352
            "a file with the name 'policy'.");
353
            
354
        }
355
        
356
        
357
        // deserialize the ReplicationPolicy
358
        replPolicyStream = new FileInputStream(replPolicyFile);
359
        policy = TypeMarshaller.unmarshalTypeFromStream(ReplicationPolicy.class, replPolicyStream);
360
        
361
        return policy;
362
        
363
    }
364

    
365
    /**
366
     * Parse the replica metadata document out of the mime-multipart form data
367
     * 
368
     * @return replica  the encoded replica
369
     * @throws ServiceFailure
370
     * @throws InvalidRequest
371
     * @throws IOException
372
     * @throws InstantiationException
373
     * @throws IllegalAccessException
374
     * @throws JiBXException
375
     */
376
    protected Replica collectReplicaMetadata() 
377
        throws ServiceFailure, InvalidRequest {
378
        
379
        Replica replica = null;
380
        File tmpDir = getTempDirectory();
381
        MultipartRequest mr = null;
382
        Map<String, File> mmFileParts = null;
383
        File replicaFile = null;
384
        InputStream replicaStream = null;
385
        
386
        // Read the incoming data from its Mime Multipart encoding
387
        logMetacat.debug("Parsing Replica from the mime multipart entity");
388

    
389
        // handle MMP inputs
390
        MultipartRequestResolver mrr = 
391
            new MultipartRequestResolver(tmpDir.getAbsolutePath(),1000000000, 0);
392
        
393
        try {
394
            mr = mrr.resolveMultipart(request);
395
            logMetacat.debug("Resolved the Replica multipart request.");
396
            
397
        } catch (IOException e) {
398
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
399
                e.getMessage());
400
            
401
        } catch (FileUploadException e) {
402
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
403
                    e.getMessage());
404
            
405
        } catch (Exception e) {
406
            throw new ServiceFailure("4852", "Couldn't resolve the multipart request: " +
407
                    e.getMessage());
408
            
409
        }
410
        
411
        // get the map of file parts
412
        mmFileParts = mr.getMultipartFiles();
413
        
414
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
415
            throw new InvalidRequest("4853", "The multipart request must include " +
416
                "a file with the name 'replicaMetadata'.");
417
            
418
        }
419
        
420
        multipartparams = mr.getMultipartParameters();
421
        replicaFile = mmFileParts.get("replicaMetadata");
422
        
423
        if ( replicaFile == null ) {
424
            throw new InvalidRequest("4853", "The multipart request must include " +
425
            "a file with the name 'replicaMetadata'.");
426
            
427
        }
428
        
429
        
430
        // deserialize the ReplicationPolicy
431
        try {
432
            replicaStream = new FileInputStream(replicaFile);
433
        } catch (FileNotFoundException e) {
434
            throw new ServiceFailure("4852", "Couldn't find the multipart file: " +
435
                    e.getMessage());
436
            
437
        }
438
        
439
        try {
440
            replica = TypeMarshaller.unmarshalTypeFromStream(Replica.class, replicaStream);
441
        } catch (IOException e) {
442
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
443
                    e.getMessage());
444
            
445
        } catch (InstantiationException e) {
446
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
447
                    e.getMessage());
448
            
449
        } catch (IllegalAccessException e) {
450
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
451
                    e.getMessage());
452
            
453
        } catch (JiBXException e) {
454
            throw new ServiceFailure("4852", "Couldn't deserialize the replica document: " +
455
                    e.getMessage());
456
            
457
        }
458
        
459
        return replica;
460
        
461
    }
462
    
463
    protected AccessPolicy collectAccessPolicy() 
464
        throws IOException, ServiceFailure, InvalidRequest, JiBXException, 
465
        InstantiationException, IllegalAccessException, ParserConfigurationException, 
466
        SAXException  {
467
		
468
		// Read the incoming data from its Mime Multipart encoding
469
		logMetacat.debug("Disassembling MIME multipart form");
470
		InputStream ap = null;
471

    
472
		// handle MMP inputs
473
		File tmpDir = getTempDirectory();
474
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
475
		MultipartRequestResolver mrr = 
476
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
477
		MultipartRequest mr = null;
478
		try {
479
			mr = mrr.resolveMultipart(request);
480
		} catch (Exception e) {
481
			throw new ServiceFailure("2161", 
482
					"Could not resolve multipart: " + e.getMessage());
483
		}
484
		logMetacat.debug("resolved multipart request");
485
		Map<String, File> files = mr.getMultipartFiles();
486
		if (files == null || files.keySet() == null) {
487
			throw new InvalidRequest("2163",
488
					"must have multipart file with name 'accessPolicy'");
489
		}
490
		logMetacat.debug("got multipart files");
491

    
492
		multipartparams = mr.getMultipartParameters();
493

    
494
		File apFile = files.get("accessPolicy");
495
		if (apFile == null) {
496
			throw new InvalidRequest("2163",
497
					"Missing the required file-part 'accessPolicy' from the multipart request.");
498
		}
499
		logMetacat.debug("apFile: " + apFile.getAbsolutePath());
500
		ap = new FileInputStream(apFile);
501
	
502
		AccessPolicy accessPolicy = TypeMarshaller.unmarshalTypeFromStream(AccessPolicy.class, ap);
503
		return accessPolicy;
504
	}
505
    
506
    protected SystemMetadata collectSystemMetadata() 
507
        throws IOException, FileUploadException, ServiceFailure, InvalidRequest, 
508
        JiBXException, InstantiationException, IllegalAccessException  {
509
		
510
		// Read the incoming data from its Mime Multipart encoding
511
		logMetacat.debug("Disassembling MIME multipart form");
512
		InputStream sysmeta = null;
513

    
514
		// handle MMP inputs
515
		File tmpDir = getTempDirectory();
516
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
517
		MultipartRequestResolver mrr = 
518
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
519
		MultipartRequest mr = null;
520
		try {
521
			mr = mrr.resolveMultipart(request);
522
		} catch (Exception e) {
523
			throw new ServiceFailure("1202", 
524
					"Could not resolve multipart: " + e.getMessage());
525
		}
526
		logMetacat.debug("resolved multipart request");
527
		Map<String, File> files = mr.getMultipartFiles();
528
		if (files == null) {
529
			throw new ServiceFailure("1202",
530
					"register meta must have multipart file with name 'sysmeta'");
531
		}
532
		logMetacat.debug("got multipart files");
533

    
534
		if (files.keySet() == null) {
535
			logMetacat.error("No file keys in MMP request.");
536
			throw new ServiceFailure(
537
					"1202",
538
					"No file keys found in MMP.  "
539
							+ "register meta must have multipart file with name 'sysmeta'");
540
		}
541

    
542
		// for logging purposes, dump out the key-value pairs that
543
		// constitute the request
544
		// 3 types exist: request params, multipart params, and
545
		// multipart files
546
		Iterator it = files.keySet().iterator();
547
		logMetacat.debug("iterating through request parts: " + it);
548
		while (it.hasNext()) {
549
			String key = (String) it.next();
550
			logMetacat.debug("files key: " + key);
551
			logMetacat.debug("files value: " + files.get(key));
552
		}
553

    
554
		multipartparams = mr.getMultipartParameters();
555
		it = multipartparams.keySet().iterator();
556
		while (it.hasNext()) {
557
			String key = (String) it.next();
558
			logMetacat.debug("multipartparams key: " + key);
559
			logMetacat.debug("multipartparams value: " + multipartparams.get(key));
560
		}
561

    
562
		it = params.keySet().iterator();
563
		while (it.hasNext()) {
564
			String key = (String) it.next();
565
			logMetacat.debug("param key: " + key);
566
			logMetacat.debug("param value: " + params.get(key));
567
		}
568
		logMetacat.debug("done iterating the request...");
569

    
570
		File smFile = files.get("sysmeta");
571
		if (smFile == null) {
572
			throw new InvalidRequest("1102",
573
					"Missing the required file-part 'sysmeta' from the multipart request.");
574
		}
575
		logMetacat.debug("smFile: " + smFile.getAbsolutePath());
576
		sysmeta = new FileInputStream(smFile);
577
	
578
		logMetacat.debug("Commence creation...");
579
		SystemMetadata systemMetadata = TypeMarshaller.unmarshalTypeFromStream(SystemMetadata.class, sysmeta);
580
		return systemMetadata;
581
	}
582
    
583
    /**
584
     * Process the MMP request that includes files for each param
585
     * @return map of param key and the temp file that contains the encoded information
586
     * @throws ServiceFailure
587
     * @throws InvalidRequest
588
     */
589
    protected Map<String, File> collectMultipartFiles() 
590
        throws ServiceFailure, InvalidRequest {
591
    	
592
        // Read the incoming data from its Mime Multipart encoding
593
        logMetacat.debug("Disassembling MIME multipart form");
594
        
595
        // handle MMP inputs
596
        File tmpDir = getTempDirectory();
597
        logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
598
        MultipartRequestResolver mrr = 
599
        	new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
600
        MultipartRequest mr = null;
601
		    try {
602
		    	  mr = mrr.resolveMultipart(request);
603
            
604
		    } catch (Exception e) {
605
                throw new ServiceFailure("1202", 
606
                		"Could not resolve multipart files: " + e.getMessage());
607
		    }
608
        logMetacat.debug("resolved multipart request");
609
        Map<String, File> files = mr.getMultipartFiles();
610
        if (files == null) {
611
            throw new ServiceFailure("1202", "no multipart files found");
612
        }
613
        logMetacat.debug("got multipart files");
614
        
615
        if (files.keySet() == null) {
616
            logMetacat.error("No file keys in MMP request.");
617
            throw new ServiceFailure("1202", "No file keys found in MMP.");
618
        }
619
        
620
        multipartparams = mr.getMultipartParameters();
621

    
622
		    // for logging purposes, dump out the key-value pairs that constitute the request
623
		    // 3 types exist: request params, multipart params, and multipart files
624
        if (logMetacat.isDebugEnabled()) {
625
	        Iterator<String> it = files.keySet().iterator();
626
	        logMetacat.debug("iterating through files");
627
	        while (it.hasNext()) {
628
	            String key = it.next();
629
	            logMetacat.debug("files key: " + key);
630
	            logMetacat.debug("files value: " + files.get(key));
631
	        }
632
	        
633
	        it = multipartparams.keySet().iterator();
634
	        logMetacat.debug("iterating through multipartparams");
635
	        while (it.hasNext()) {
636
	            String key = (String)it.next();
637
	            logMetacat.debug("multipartparams key: " + key);
638
	            logMetacat.debug("multipartparams value: " + multipartparams.get(key));
639
	        }
640
	        
641
	        it = params.keySet().iterator();
642
	        logMetacat.debug("iterating through params");
643
	        while (it.hasNext()) {
644
	            String key = (String)it.next();
645
	            logMetacat.debug("param key: " + key);
646
	            logMetacat.debug("param value: " + params.get(key));
647
	        }
648
	        logMetacat.debug("done iterating the request...");
649
        }
650
        
651
        return files;
652
    }
653
    
654
		/**
655
     *  copies request parameters to a hashtable which is given as argument to 
656
     *  native metacathandler functions  
657
     */
658
    protected void initParams() {
659

    
660
        String name = null;
661
        String[] value = null;
662
        Enumeration paramlist = request.getParameterNames();
663
        while (paramlist.hasMoreElements()) {
664
            name = (String) paramlist.nextElement();
665
            value = request.getParameterValues(name);
666
            params.put(name, value);
667
        }
668
    }
669
    
670
    /**
671
     * Collect the multipart params from the request
672
     * @throws Exception 
673
     */
674
	protected void initMultipartParams() throws Exception {
675
		
676
		// Read the incoming data from its Mime Multipart encoding
677
		logMetacat.debug("Disassembling MIME multipart form");
678
	
679
		// handle MMP inputs
680
		File tmpDir = getTempDirectory();
681
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
682
		MultipartRequestResolver mrr = 
683
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
684
		MultipartRequest mr = mrr.resolveMultipart(request);
685
		
686
		multipartparams = mr.getMultipartParameters();
687
	}
688
   
689
    /**
690
     * locate the boundary marker for an MMP
691
     * @param is
692
     * @return
693
     * @throws IOException
694
     */
695
    protected static String[] findBoundaryString(InputStream is)
696
        throws IOException {
697
        String[] endResult = new String[2];
698
        String boundary = "";
699
        String searchString = "boundary=";
700
        byte[] b = new byte[1024];
701
        int numbytes = is.read(b, 0, 1024);
702

    
703
        while(numbytes != -1)
704
        {
705
            String s = new String(b, 0, numbytes);
706
            int searchStringIndex = s.indexOf(searchString);
707
            
708
            if(s.indexOf("\"", searchStringIndex + searchString.length() + 1) == -1)
709
            { //the end of the boundary is in the next byte array
710
                boundary = s.substring(searchStringIndex + searchString.length() + 1, s.length());
711
            }
712
            else if(!boundary.startsWith("--"))
713
            { //we can read the whole boundary from this byte array
714
                boundary = s.substring(searchStringIndex + searchString.length() + 1, 
715
                    s.indexOf("\"", searchStringIndex + searchString.length() + 1));
716
                boundary = "--" + boundary;
717
                endResult[0] = boundary;
718
                endResult[1] = s.substring(s.indexOf("\"", searchStringIndex + searchString.length() + 1) + 1,
719
                        s.length());
720
                break;
721
            }
722
            else
723
            { //we're now reading the 2nd byte array to get the rest of the boundary
724
                searchString = "\"";
725
                searchStringIndex = s.indexOf(searchString);
726
                boundary += s.substring(0, searchStringIndex);
727
                boundary = "--" + boundary;
728
                endResult[0] = boundary;
729
                endResult[1] = s.substring(s.indexOf("\"", searchStringIndex + searchString.length() + 1) + 1,
730
                        s.length());
731
                break;
732
            }
733
        }
734
        return endResult;
735
    }
736
    
737
    /**
738
     * return the directory where temp files are stored
739
     * @return
740
     */
741
    protected static File getTempDirectory()
742
    {
743
        File tmpDir = null;
744
        Logger logMetacat = Logger.getLogger(D1ResourceHandler.class);
745
        try {
746
            tmpDir = new File(PropertyService.getProperty("application.tempDir"));
747
        }
748
        catch(PropertyNotFoundException pnfe) {
749
            logMetacat.error("D1ResourceHandler.writeMMPPartstoFiles: " +
750
                    "application.tmpDir not found.  Using /tmp instead.");
751
            tmpDir = new File("/tmp");
752
        }
753
        return tmpDir;
754
    }
755
    
756
    /**
757
     * Prints xml response
758
     * @param message Message to be displayed
759
     * @param response Servlet response that xml message will be printed 
760
     * */
761
    protected void printError(String message, HttpServletResponse response) {
762
        try {
763
            logMetacat.error("D1ResourceHandler: Printing error to servlet response: " + message);
764
            PrintWriter out = response.getWriter();
765
            response.setContentType("text/xml");
766
            out.println("<?xml version=\"1.0\"?>");
767
            out.println("<error>");
768
            out.println(message);
769
            out.println("</error>");
770
            out.close();
771
        } catch (IOException e) {
772
            e.printStackTrace();
773
        }
774
    }
775
    
776
    /**
777
     * serialize a D1 exception using jibx
778
     * @param e
779
     * @param out
780
     */
781
    protected void serializeException(BaseException e, OutputStream out) {
782
        // TODO: Use content negotiation to determine which return format to use
783
        response.setContentType("text/xml");
784
        response.setStatus(e.getCode());
785
        
786
        logMetacat.error("D1ResourceHandler: Serializing exception with code " + e.getCode() + ": " + e.getMessage());
787
        e.printStackTrace();
788
        
789
        try {
790
            IOUtils.write(e.serialize(BaseException.FMT_XML), out);
791
        } catch (IOException e1) {
792
            logMetacat.error("Error writing exception to stream. " 
793
                    + e1.getMessage());
794
        }
795
    }
796

    
797
}
(4-4/9)