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.TypeMarshaller;
59
import org.jibx.runtime.JiBXException;
60
import org.xml.sax.SAXException;
61

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
218
        // get the map of file parts
219
        mmFileParts = mr.getMultipartFiles();
220
        
221
        if ( mmFileParts == null || mmFileParts.keySet() == null) {
222
            logMetacat.debug("BaseException for setReplicationStatus is null");            
223
        }
224
        
225
        multipartparams = mr.getMultipartParameters();
226
        exceptionFile = mmFileParts.get("failure");
227
        
228
        if ( exceptionFile != null ) {
229
            
230
            // deserialize the ReplicationPolicy
231
            exceptionFileStream = new FileInputStream(exceptionFile);
232
            failure = TypeMarshaller.unmarshalTypeFromStream(BaseException.class, exceptionFileStream);
233
                
234
        }
235
        
236
        
237
        return failure;
238
        
239
    }
240
    
241
    /**
242
     * Parse the replication policy document out of the mime-multipart form data
243
     * 
244
     * @return policy  the encoded policy
245
     * @throws ServiceFailure
246
     * @throws InvalidRequest
247
     * @throws IOException
248
     * @throws InstantiationException
249
     * @throws IllegalAccessException
250
     * @throws JiBXException
251
     */
252
    protected ReplicationPolicy collectReplicationPolicy() 
253
        throws ServiceFailure, InvalidRequest, IOException, InstantiationException, 
254
        IllegalAccessException, JiBXException {
255
        
256
        ReplicationPolicy policy = null;
257
        File tmpDir = getTempDirectory();
258
        MultipartRequest mr = null;
259
        Map<String, File> mmFileParts = null;
260
        File replPolicyFile = null;
261
        InputStream replPolicyStream = null;
262
        
263
        // Read the incoming data from its Mime Multipart encoding
264
        logMetacat.debug("Parsing ReplicationPolicy from the mime multipart entity");
265

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

    
315
    /**
316
     * Parse the replica metadata document out of the mime-multipart form data
317
     * 
318
     * @return replica  the encoded replica
319
     * @throws ServiceFailure
320
     * @throws InvalidRequest
321
     * @throws IOException
322
     * @throws InstantiationException
323
     * @throws IllegalAccessException
324
     * @throws JiBXException
325
     */
326
    protected Replica collectReplicaMetadata() 
327
        throws ServiceFailure, InvalidRequest {
328
        
329
        Replica replica = null;
330
        File tmpDir = getTempDirectory();
331
        MultipartRequest mr = null;
332
        Map<String, File> mmFileParts = null;
333
        File replicaFile = null;
334
        InputStream replicaStream = null;
335
        
336
        // Read the incoming data from its Mime Multipart encoding
337
        logMetacat.debug("Parsing Replica from the mime multipart entity");
338

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

    
422
		// handle MMP inputs
423
		File tmpDir = getTempDirectory();
424
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
425
		MultipartRequestResolver mrr = 
426
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
427
		MultipartRequest mr = null;
428
		try {
429
			mr = mrr.resolveMultipart(request);
430
		} catch (Exception e) {
431
			throw new ServiceFailure("2161", 
432
					"Could not resolve multipart: " + e.getMessage());
433
		}
434
		logMetacat.debug("resolved multipart request");
435
		Map<String, File> files = mr.getMultipartFiles();
436
		if (files == null || files.keySet() == null) {
437
			throw new InvalidRequest("2163",
438
					"must have multipart file with name 'accessPolicy'");
439
		}
440
		logMetacat.debug("got multipart files");
441

    
442
		multipartparams = mr.getMultipartParameters();
443

    
444
		File apFile = files.get("accessPolicy");
445
		if (apFile == null) {
446
			throw new InvalidRequest("2163",
447
					"Missing the required file-part 'accessPolicy' from the multipart request.");
448
		}
449
		logMetacat.debug("apFile: " + apFile.getAbsolutePath());
450
		ap = new FileInputStream(apFile);
451
	
452
		AccessPolicy accessPolicy = TypeMarshaller.unmarshalTypeFromStream(AccessPolicy.class, ap);
453
		return accessPolicy;
454
	}
455
    
456
    protected SystemMetadata collectSystemMetadata() 
457
        throws IOException, FileUploadException, ServiceFailure, InvalidRequest, 
458
        JiBXException, InstantiationException, IllegalAccessException  {
459
		
460
		// Read the incoming data from its Mime Multipart encoding
461
		logMetacat.debug("Disassembling MIME multipart form");
462
		InputStream sysmeta = null;
463

    
464
		// handle MMP inputs
465
		File tmpDir = getTempDirectory();
466
		logMetacat.debug("temp dir: " + tmpDir.getAbsolutePath());
467
		MultipartRequestResolver mrr = 
468
			new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
469
		MultipartRequest mr = null;
470
		try {
471
			mr = mrr.resolveMultipart(request);
472
		} catch (Exception e) {
473
			throw new ServiceFailure("1202", 
474
					"Could not resolve multipart: " + e.getMessage());
475
		}
476
		logMetacat.debug("resolved multipart request");
477
		Map<String, File> files = mr.getMultipartFiles();
478
		if (files == null) {
479
			throw new ServiceFailure("1202",
480
					"register meta must have multipart file with name 'sysmeta'");
481
		}
482
		logMetacat.debug("got multipart files");
483

    
484
		if (files.keySet() == null) {
485
			logMetacat.error("No file keys in MMP request.");
486
			throw new ServiceFailure(
487
					"1202",
488
					"No file keys found in MMP.  "
489
							+ "register meta must have multipart file with name 'sysmeta'");
490
		}
491

    
492
		// for logging purposes, dump out the key-value pairs that
493
		// constitute the request
494
		// 3 types exist: request params, multipart params, and
495
		// multipart files
496
		Iterator it = files.keySet().iterator();
497
		logMetacat.debug("iterating through request parts: " + it);
498
		while (it.hasNext()) {
499
			String key = (String) it.next();
500
			logMetacat.debug("files key: " + key);
501
			logMetacat.debug("files value: " + files.get(key));
502
		}
503

    
504
		multipartparams = mr.getMultipartParameters();
505
		it = multipartparams.keySet().iterator();
506
		while (it.hasNext()) {
507
			String key = (String) it.next();
508
			logMetacat.debug("multipartparams key: " + key);
509
			logMetacat.debug("multipartparams value: " + multipartparams.get(key));
510
		}
511

    
512
		it = params.keySet().iterator();
513
		while (it.hasNext()) {
514
			String key = (String) it.next();
515
			logMetacat.debug("param key: " + key);
516
			logMetacat.debug("param value: " + params.get(key));
517
		}
518
		logMetacat.debug("done iterating the request...");
519

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

    
567
		// for logging purposes, dump out the key-value pairs that constitute the request
568
		// 3 types exist: request params, multipart params, and multipart files
569
        Iterator it = files.keySet().iterator();
570
        logMetacat.debug("iterating through files");
571
        while (it.hasNext()) {
572
            String key = (String)it.next();
573
            logMetacat.debug("files key: " + key);
574
            logMetacat.debug("files value: " + files.get(key));
575
        }
576
        
577
        multipartparams = mr.getMultipartParameters();
578
        it = multipartparams.keySet().iterator();
579
        logMetacat.debug("iterating through multipartparams");
580
        while (it.hasNext()) {
581
            String key = (String)it.next();
582
            logMetacat.debug("multipartparams key: " + key);
583
            logMetacat.debug("multipartparams value: " + multipartparams.get(key));
584
        }
585
        
586
        it = params.keySet().iterator();
587
        logMetacat.debug("iterating through params");
588
        while (it.hasNext()) {
589
            String key = (String)it.next();
590
            logMetacat.debug("param key: " + key);
591
            logMetacat.debug("param value: " + params.get(key));
592
        }
593
        logMetacat.debug("done iterating the request...");
594

    
595
        File smFile = files.get("sysmeta");
596
		if (smFile == null) {
597
		    throw new InvalidRequest("1102", "Missing the required file-part 'sysmeta' from the multipart request.");
598
		}
599
        logMetacat.debug("smFile: " + smFile.getAbsolutePath());
600
        File objFile = files.get("object");
601
		if (objFile == null) {
602
		    throw new InvalidRequest("1102", "Missing the required file-part 'object' from the multipart request.");
603
		}
604
        logMetacat.debug("objectfile: " + objFile.getAbsolutePath());
605
        
606
        return files;
607
    }
608
    
609
		/**
610
     *  copies request parameters to a hashtable which is given as argument to 
611
     *  native metacathandler functions  
612
     */
613
    protected void initParams() {
614

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

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

    
752
}
(4-4/9)