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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
494
		multipartparams = mr.getMultipartParameters();
495

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

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

    
542
		if (files.keySet() == null) {
543
			logMetacat.error("No file keys in MMP request.");
544
			throw new ServiceFailure(
545
					"1202",
546
					"No file keys found in MMP.  "
547
							+ "register meta must have multipart file with name 'sysmeta'");
548
		}
549

    
550
		// for logging purposes, dump out the key-value pairs that
551
		// constitute the request
552
		// 3 types exist: request params, multipart params, and
553
		// multipart files
554
		Iterator it = files.keySet().iterator();
555
		logMetacat.debug("iterating through request parts: " + it);
556
		while (it.hasNext()) {
557
			String key = (String) it.next();
558
			logMetacat.debug("files key: " + key);
559
			logMetacat.debug("files value: " + files.get(key));
560
		}
561

    
562
		multipartparams = mr.getMultipartParameters();
563
		it = multipartparams.keySet().iterator();
564
		while (it.hasNext()) {
565
			String key = (String) it.next();
566
			logMetacat.debug("multipartparams key: " + key);
567
			logMetacat.debug("multipartparams value: " + multipartparams.get(key));
568
		}
569

    
570
		it = params.keySet().iterator();
571
		while (it.hasNext()) {
572
			String key = (String) it.next();
573
			logMetacat.debug("param key: " + key);
574
			logMetacat.debug("param value: " + params.get(key));
575
		}
576
		logMetacat.debug("done iterating the request...");
577

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

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

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

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

    
805
}
(4-4/9)