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
			
523
		} catch (Exception e) {
524
		  if ( logMetacat.isDebugEnabled() ) {
525
		      e.printStackTrace();
526
		      
527
		  }
528
			throw new ServiceFailure("1202", 
529
					"Could not resolve multipart: " + e.getMessage());
530
			
531
		}
532
		logMetacat.debug("resolved multipart request");
533
		Map<String, File> files = mr.getMultipartFiles();
534
		if (files == null) {
535
			throw new ServiceFailure("1202",
536
					"register meta must have multipart file with name 'sysmeta'");
537
		}
538
		logMetacat.debug("got multipart files");
539

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

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

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

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

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

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

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

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

    
803
}
(4-4/9)