Mercurial Hosting > nabble
comparison src/nabble/model/FileUpload.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children | b74139388033 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7ecd1a4ef557 |
---|---|
1 package nabble.model; | |
2 | |
3 import fschmidt.db.DbDatabase; | |
4 import fschmidt.db.Listener; | |
5 import fschmidt.html.HtmlTag; | |
6 import fschmidt.util.java.ImageUtils; | |
7 import nabble.view.web.forum.FileDownload; | |
8 import org.apache.commons.fileupload.FileItem; | |
9 import org.apache.commons.fileupload.FileItemHeaders; | |
10 import org.slf4j.Logger; | |
11 import org.slf4j.LoggerFactory; | |
12 | |
13 import javax.imageio.ImageIO; | |
14 import java.awt.image.BufferedImage; | |
15 import java.awt.image.ImagingOpException; | |
16 import java.io.ByteArrayInputStream; | |
17 import java.io.ByteArrayOutputStream; | |
18 import java.io.FilterInputStream; | |
19 import java.io.IOException; | |
20 import java.io.InputStream; | |
21 import java.net.URL; | |
22 import java.sql.Connection; | |
23 import java.sql.PreparedStatement; | |
24 import java.sql.ResultSet; | |
25 import java.sql.SQLException; | |
26 import java.sql.Statement; | |
27 import java.util.ArrayList; | |
28 import java.util.Date; | |
29 import java.util.HashMap; | |
30 import java.util.HashSet; | |
31 import java.util.Iterator; | |
32 import java.util.List; | |
33 import java.util.Map; | |
34 import java.util.Set; | |
35 | |
36 | |
37 public final class FileUpload { | |
38 private static final Logger logger = LoggerFactory.getLogger(FileUpload.class); | |
39 | |
40 public static final int MAX_IMAGE_SIZE = 1048576; | |
41 public static final int MAX_FILE_SIZE = 5242880; | |
42 | |
43 public static class FileDetails { | |
44 private String name; | |
45 private Date date; | |
46 | |
47 public FileDetails(String name, Date date) { | |
48 this.name = name; | |
49 this.date = date; | |
50 } | |
51 | |
52 public String getName() { return name; } | |
53 public Date getDate() { return date; } | |
54 } | |
55 | |
56 private static void addToSql(Message.Source src,StringBuilder sql) { | |
57 Message.SourceType type = src.getMessageSourceType(); | |
58 sql.append( " from file_" ).append( type.getName() ); | |
59 String idField = type.getIdField(); | |
60 if( idField == null ) { | |
61 sql.append( " where true" ); | |
62 } else { | |
63 sql.append( " where " ).append( idField ).append( " = ?" ); | |
64 } | |
65 } | |
66 | |
67 private static int setParams(Message.Source src,PreparedStatement pstmt) | |
68 throws SQLException | |
69 { | |
70 int i = 0; | |
71 if( src.getMessageSourceType().getIdField() != null ) { | |
72 pstmt.setLong(++i,src.getSourceId()); | |
73 } | |
74 return i; | |
75 } | |
76 | |
77 public static InputStream getFileContent(Message.Source src,String name) { | |
78 if( src==null ) | |
79 return null; | |
80 Message.SourceType type = src.getMessageSourceType(); | |
81 try { | |
82 final Connection con = src.getSite().getDb().getConnection(); | |
83 StringBuilder sql = new StringBuilder(); | |
84 sql.append( "select content" ); | |
85 addToSql(src,sql); | |
86 sql.append( " and name = ?" ); | |
87 final PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
88 boolean isDone = false; | |
89 try { | |
90 int i = setParams(src,pstmt); | |
91 pstmt.setString(++i,name); | |
92 ResultSet rs = pstmt.executeQuery(); | |
93 if( !rs.next() ) | |
94 return null; | |
95 InputStream rtn = new FilterInputStream(rs.getBinaryStream("content")) { | |
96 public void close() throws IOException { | |
97 super.close(); | |
98 try { | |
99 pstmt.close(); | |
100 con.close(); | |
101 } catch(SQLException e) { | |
102 throw new RuntimeException(e); | |
103 } | |
104 } | |
105 }; | |
106 isDone = true; | |
107 return rtn; | |
108 } finally { | |
109 if( !isDone ) { | |
110 pstmt.close(); | |
111 con.close(); | |
112 } | |
113 } | |
114 } catch(SQLException e) { | |
115 throw new RuntimeException(e); | |
116 } | |
117 } | |
118 | |
119 static boolean hasFile(Message.Source src,String name) { | |
120 Message.SourceType type = src.getMessageSourceType(); | |
121 try { | |
122 final Connection con = src.getSite().getDb().getConnection(); | |
123 StringBuilder sql = new StringBuilder(); | |
124 sql.append( "select 'whatever'" ); | |
125 addToSql(src,sql); | |
126 sql.append( " and name = ?" ); | |
127 final PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
128 try { | |
129 int i = setParams(src,pstmt); | |
130 pstmt.setString(++i,name); | |
131 return pstmt.executeQuery().next(); | |
132 } finally { | |
133 pstmt.close(); | |
134 con.close(); | |
135 } | |
136 } catch(SQLException e) { | |
137 throw new RuntimeException(e); | |
138 } | |
139 } | |
140 | |
141 public static FileDetails[] getFileDetails(Message.Source src,String prefix) { | |
142 Message.SourceType type = src.getMessageSourceType(); | |
143 try { | |
144 final Connection con = src.getSite().getDb().getConnection(); | |
145 StringBuilder sql = new StringBuilder(); | |
146 sql.append( "select name, date_" ); | |
147 addToSql(src,sql); | |
148 if( prefix != null ) | |
149 sql.append( " and name like '" ).append( prefix ).append( "%'" ); | |
150 sql.append( " order by name" ); | |
151 final PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
152 try { | |
153 setParams(src,pstmt); | |
154 List<FileDetails> names = new ArrayList<FileDetails>(); | |
155 ResultSet set = pstmt.executeQuery(); | |
156 while (set.next()) { | |
157 names.add(new FileDetails(set.getString("name"), set.getDate("date_"))); | |
158 } | |
159 return names.toArray(new FileDetails[0]); | |
160 } finally { | |
161 pstmt.close(); | |
162 con.close(); | |
163 } | |
164 } catch(SQLException e) { | |
165 throw new RuntimeException(e); | |
166 } | |
167 } | |
168 | |
169 public static String getName(FileItem fi) { | |
170 String[] a = fi.getName().split("[\\\\/:]"); | |
171 String[] b = a[a.length-1].split("\\."); | |
172 String ext2 = b[b.length-1]; | |
173 int n = (int)(Math.random()*1000); | |
174 if(b[0].equals("image")) | |
175 b[0] = b[0]+n; | |
176 return b[0]+"."+ext2; | |
177 } | |
178 | |
179 public static String uploadImage(final FileItem fi,Message.Source src, int resize) | |
180 throws ModelException | |
181 { | |
182 try { | |
183 return uploadImage1(fi,src,resize); | |
184 } catch(IOException e) { | |
185 throw ModelException.newInstance("upload_image_failed",e); | |
186 } | |
187 } | |
188 | |
189 private static String uploadImage1(final FileItem fi,Message.Source src, int resize) | |
190 throws ModelException, IOException | |
191 { | |
192 InputStream in = fi.getInputStream(); | |
193 BufferedImage bi; | |
194 try { | |
195 bi = ImageIO.read(in); | |
196 } catch(IllegalArgumentException e) { | |
197 throw ModelException.newInstance("upload_image_failed",e); | |
198 } catch (RuntimeException e) { | |
199 throw ModelException.newInstance("unknown_image_error",e); | |
200 } | |
201 in.close(); | |
202 if (bi == null) | |
203 throw ModelException.newInstance("unsupported_image_type","Unsupported image type - please use PNG, JPG or GIF."); | |
204 | |
205 String filename = getName(fi); | |
206 filename = filename.replaceAll("[ ']+","_"); // Replace spaces and single quotes with underscores | |
207 int iDot = filename.lastIndexOf('.'); | |
208 if( iDot == -1 ) | |
209 throw ModelException.newInstance("file_has_no_ending","File must have ending"); | |
210 String ending = filename.substring(iDot+1).toLowerCase(); | |
211 InputStream bais; | |
212 long size; | |
213 if (resize > 0) { | |
214 try { | |
215 bi = ImageUtils.getThumbnail(bi, resize, resize); | |
216 final byte[] contents = ImageUtils.asOutputStream(bi, ending).toByteArray(); | |
217 bi = null; | |
218 size = contents.length; | |
219 bais = new ByteArrayInputStream(contents); | |
220 } catch (ImagingOpException e) { | |
221 throw ModelException.newInstance("unable_to_resize_image","Unable to resize image", e); | |
222 } | |
223 } else { | |
224 bi = null; | |
225 bais = fi.getInputStream(); | |
226 size = fi.getSize(); | |
227 } | |
228 final InputStream inputStream = bais; | |
229 if (size <= MAX_IMAGE_SIZE) { | |
230 filename = filename.substring(0,iDot+1) + ending; | |
231 return uploadFile2(size,filename,src, true, | |
232 new InputStreamFactory() { | |
233 public InputStream in() throws IOException { | |
234 return inputStream; | |
235 } | |
236 } | |
237 ); | |
238 } else { | |
239 throw ModelException.newInstance("image_too_large","Image is too large: use the resize option to make it smaller. Maximum size 1MB."); | |
240 } | |
241 } | |
242 | |
243 /* | |
244 static boolean isDifferent(final FileItem fi,Message.Source src) | |
245 throws ModelException | |
246 { | |
247 try { | |
248 InputStream inDb = getFileContent(src,fi.getName()); | |
249 if( inDb==null ) | |
250 return true; | |
251 InputStream inFi = null; | |
252 try { | |
253 inFi = fi.getInputStream(); | |
254 return IoUtils.compare(inDb,inFi) != 0; | |
255 } finally { | |
256 if (inFi != null) | |
257 inFi.close(); | |
258 inDb.close(); | |
259 } | |
260 } catch(IOException e) { | |
261 throw ModelException.newInstance("file_io_exception",e); | |
262 } | |
263 } | |
264 */ | |
265 | |
266 public static String uploadFile(final FileItem fi,Message.Source src) | |
267 throws ModelException | |
268 { | |
269 try { | |
270 return uploadFile1(fi,src); | |
271 } catch(IOException e) { | |
272 throw ModelException.newInstance("file_io_exception",e); | |
273 } | |
274 } | |
275 | |
276 private static String uploadFile1(final FileItem fi,Message.Source src) | |
277 throws ModelException, IOException | |
278 { | |
279 String filename = getName(fi); | |
280 filename = filename.replaceAll("[ ']+", "_"); // Replace spaces and single quotes with underscores | |
281 long size = fi.getSize(); | |
282 return uploadFile2(size,filename,src, true, | |
283 new InputStreamFactory() { | |
284 public InputStream in() throws IOException { | |
285 return fi.getInputStream(); | |
286 } | |
287 } | |
288 ); | |
289 } | |
290 | |
291 private static interface InputStreamFactory { | |
292 public InputStream in() throws IOException; | |
293 } | |
294 | |
295 private static String uploadFile2(long size, String filename, final Message.Source src, boolean checkSize, InputStreamFactory inf) | |
296 throws ModelException, IOException | |
297 { | |
298 if( "".equals(filename.trim()) ) | |
299 throw ModelException.newInstance("empty_filename","empty filename"); | |
300 if( size==0 ) | |
301 throw ModelException.newInstance("empty_file","empty file"); | |
302 if( size > MAX_FILE_SIZE && checkSize ) | |
303 throw ModelException.newInstance("file_is_too_large","file is too large - maximum size 5mb"); | |
304 synchronized(src) { | |
305 try { | |
306 Connection con = src.getSite().getDb().getConnection(); | |
307 try { | |
308 { | |
309 StringBuilder sql = new StringBuilder(); | |
310 sql.append( "delete" ); | |
311 addToSql(src,sql); | |
312 sql.append( " and name = ?" ); | |
313 PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
314 int i = setParams(src,pstmt); | |
315 pstmt.setString(++i,filename); | |
316 pstmt.executeUpdate(); | |
317 pstmt.close(); | |
318 } | |
319 { | |
320 StringBuilder sql = new StringBuilder(); | |
321 Message.SourceType type = src.getMessageSourceType(); | |
322 sql.append( "insert into file_" ).append( type.getName() ); | |
323 sql.append( " ( name, content" ); | |
324 String idField = type.getIdField(); | |
325 if( idField != null ) | |
326 sql.append( ", " ).append( idField ); | |
327 sql.append( " ) values (?,?" ); | |
328 if( idField != null ) | |
329 sql.append( ",?" ); | |
330 sql.append( ")" ); | |
331 PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
332 pstmt.setString(1,filename); | |
333 InputStream in = inf.in(); | |
334 pstmt.setBinaryStream(2,in,(int)size); | |
335 if( idField != null ) | |
336 pstmt.setLong(3,src.getSourceId()); | |
337 pstmt.executeUpdate(); | |
338 in.close(); | |
339 pstmt.close(); | |
340 } | |
341 return filename; | |
342 } finally { | |
343 con.close(); | |
344 src.getSite().getDb().runAfterCommit(new Runnable(){public void run(){ | |
345 fireFileUpdateListeners(src); | |
346 }}); | |
347 } | |
348 } catch(SQLException e) { | |
349 throw new RuntimeException(e); | |
350 } | |
351 } | |
352 } | |
353 | |
354 | |
355 private static List<Listener<Message.Source>> fileUpdateListeners = new ArrayList<Listener<Message.Source>>(); | |
356 | |
357 public static void addFileUpdateListener(Listener<Message.Source> listener) { | |
358 fileUpdateListeners.add(listener); | |
359 } | |
360 | |
361 static void fireFileUpdateListeners(Message.Source src) { | |
362 for( Listener<Message.Source> listener : fileUpdateListeners ) { | |
363 listener.event(src); | |
364 } | |
365 } | |
366 | |
367 | |
368 static { | |
369 NodeImpl.addPostInsertListener(new Listener<NodeImpl>(){ | |
370 public void event(NodeImpl node) { | |
371 Message.Format fmt = node.getMessage().getFormat(); | |
372 if( !(fmt instanceof MailMessageFormat) && node.getOwner() instanceof User) | |
373 fixFileTags(node.getMessage(),(User)node.getOwner()); | |
374 } | |
375 }); | |
376 NodeImpl.addPostUpdateListener(new Listener<NodeImpl>(){ | |
377 public void event(NodeImpl node) { | |
378 if( ModelHome.insideImportProcedure.get() ) | |
379 return; | |
380 Message.Format fmt = node.getMessage().getFormat(); | |
381 if( !(fmt instanceof MailMessageFormat) ) | |
382 deleteUnusedFiles(node.getMessage()); | |
383 } | |
384 }); | |
385 } | |
386 | |
387 private static void deleteUnusedFiles(Message message) { | |
388 Message.Source src = message.getSource(); | |
389 if (src == null) | |
390 return; | |
391 DbDatabase db = src.getSite().getDb(); | |
392 Message.SourceType type = src.getMessageSourceType(); | |
393 Set<String> names = getFileInfo(message.parse(),src).keySet(); | |
394 StringBuilder sql = new StringBuilder(); | |
395 sql.append( "delete" ); | |
396 addToSql(src,sql); | |
397 if( !names.isEmpty() ) { | |
398 sql.append( " and name not in (" ); | |
399 Iterator<String> iter = names.iterator(); | |
400 sql.append( db.arcana().quote(iter.next()) ); | |
401 while( iter.hasNext() ) { | |
402 sql.append( ',' ); | |
403 sql.append( db.arcana().quote(iter.next()) ); | |
404 } | |
405 sql.append( ")" ); | |
406 } | |
407 try { | |
408 Connection con = db.getConnection(); | |
409 PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
410 setParams(src,pstmt); | |
411 pstmt.executeUpdate(); | |
412 pstmt.close(); | |
413 con.close(); | |
414 } catch(SQLException e) { | |
415 throw new RuntimeException(e); | |
416 } | |
417 } | |
418 | |
419 public static void deleteFile(String fileName, Message.Source src) { | |
420 Message.SourceType type = src.getMessageSourceType(); | |
421 try { | |
422 Connection con = src.getSite().getDb().getConnection(); | |
423 try { | |
424 StringBuilder sql = new StringBuilder(); | |
425 sql.append( "delete" ); | |
426 addToSql(src,sql); | |
427 sql.append( " and name = ?" ); | |
428 PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
429 int i = setParams(src,pstmt); | |
430 pstmt.setString(++i,fileName); | |
431 pstmt.executeUpdate(); | |
432 pstmt.close(); | |
433 } finally { | |
434 con.close(); | |
435 } | |
436 } catch(SQLException e) { | |
437 throw new RuntimeException(e); | |
438 } | |
439 } | |
440 | |
441 private static void fixFileTags(Message message,User user) { | |
442 for( Object obj : message.parse() ) { | |
443 if( !(obj instanceof HtmlTag) ) | |
444 continue; | |
445 HtmlTag tag = (HtmlTag)obj; | |
446 String tagName = tag.getName().toLowerCase(); | |
447 if( tagName.equals("nabble_a") ) { | |
448 fix(tag,"href",message.getSource(),user); | |
449 } else if( tagName.equals("nabble_img") ) { | |
450 fix(tag,"src",message.getSource(),user); | |
451 } | |
452 } | |
453 } | |
454 | |
455 public static void checkFileTags(Message message,Person visitor) throws ModelException { | |
456 Set<String> fileNames = new HashSet<String>(); | |
457 if( visitor instanceof User ) { | |
458 User user = (User)visitor; | |
459 Message.Source srcTemp = Message.SourceType.getType('t').getSource(user.getSite(),user.getId()); | |
460 FileDetails[] fileDetails = getFileDetails(srcTemp, null); | |
461 for (FileDetails d : fileDetails) { | |
462 fileNames.add(d.name); | |
463 } | |
464 } | |
465 for( Object obj : message.parse() ) { | |
466 if( !(obj instanceof HtmlTag) ) | |
467 continue; | |
468 HtmlTag tag = (HtmlTag)obj; | |
469 String tagName = tag.getName().toLowerCase(); | |
470 if( tagName.equals("nabble_a") ) { | |
471 String href = HtmlTag.unquote(tag.getAttributeValue("href")); | |
472 if (!fileNames.contains(href)) | |
473 throw new ModelException.InvalidFile(href); | |
474 } else if( tagName.equals("nabble_img") ) { | |
475 String src = HtmlTag.unquote(tag.getAttributeValue("src")); | |
476 if (!fileNames.contains(src)) | |
477 throw new ModelException.InvalidFile(src); | |
478 } | |
479 } | |
480 } | |
481 | |
482 private static void fix(HtmlTag tag,String fileAttr,Message.Source src,User user) | |
483 { | |
484 String filename = HtmlTag.unquote(tag.getAttributeValue(fileAttr)); | |
485 if( filename==null ) | |
486 return; | |
487 Message.SourceType type = src.getMessageSourceType(); | |
488 try { | |
489 Connection con = src.getSite().getDb().getConnection(); | |
490 try { | |
491 { | |
492 PreparedStatement pstmt = con.prepareStatement( | |
493 "select 'x' from file_temp" | |
494 +" where user_id = ?" | |
495 +" and name = ?" | |
496 ); | |
497 pstmt.setLong(1,user.getId()); | |
498 pstmt.setString(2,filename); | |
499 ResultSet rs = pstmt.executeQuery(); | |
500 try { | |
501 if( !rs.next() ) | |
502 return; | |
503 } finally { | |
504 rs.close(); | |
505 pstmt.close(); | |
506 } | |
507 } | |
508 { | |
509 StringBuilder sql = new StringBuilder(); | |
510 sql.append( "delete" ); | |
511 addToSql(src,sql); | |
512 sql.append( " and name = ?" ); | |
513 PreparedStatement pstmt = con.prepareStatement(sql.toString()); | |
514 int i = setParams(src,pstmt); | |
515 pstmt.setString(++i,filename); | |
516 pstmt.executeUpdate(); | |
517 pstmt.close(); | |
518 } | |
519 PreparedStatement pstmt = con.prepareStatement( | |
520 "insert into file_" + type.getName() | |
521 +" (" + type.getIdField() + ", name, content)" | |
522 +" select ?, name, content" | |
523 +" from file_temp" | |
524 +" where user_id = ?" | |
525 +" and name=?" | |
526 ); | |
527 pstmt.setLong(1,src.getSourceId()); | |
528 pstmt.setLong(2,user.getId()); | |
529 pstmt.setString(3,filename); | |
530 pstmt.executeUpdate(); | |
531 pstmt.close(); | |
532 { | |
533 Statement stmt = con.createStatement(); | |
534 stmt.executeUpdate( | |
535 "delete from file_temp" | |
536 +" where date_ < " + Db.arcana.dateSub("now()",1,"day") | |
537 ); | |
538 stmt.close(); | |
539 } | |
540 } finally { | |
541 con.close(); | |
542 } | |
543 } catch(SQLException e) { | |
544 throw new RuntimeException(e); | |
545 } | |
546 } | |
547 | |
548 public static void processFileTags(List<Object> list,Message.Source src) { | |
549 if( src == null ) | |
550 return; | |
551 for( Object obj : list ) { | |
552 if( !(obj instanceof HtmlTag) ) | |
553 continue; | |
554 HtmlTag tag = (HtmlTag)obj; | |
555 String tagName = tag.getName().toLowerCase(); | |
556 if( tagName.equals("nabble_a") ) { | |
557 String filename = HtmlTag.unquote(tag.getAttributeValue("href")); | |
558 if( filename==null ) | |
559 continue; | |
560 String url = getUrl(filename,src); | |
561 tag.setAttribute("href",HtmlTag.quote(url)); | |
562 tag.setName("a"); | |
563 if( tag.getAttributeValue("target") == null ) { | |
564 tag.setAttribute("target","\"_top\""); | |
565 } | |
566 } else if( tagName.equals("/nabble_a") ) { | |
567 tag.setName("/a"); | |
568 } else if( tagName.equals("nabble_img") ) { | |
569 String filename = HtmlTag.unquote(tag.getAttributeValue("src")); | |
570 if( filename==null ) | |
571 continue; | |
572 String url = getUrl(filename,src); | |
573 tag.setAttribute("src",HtmlTag.quote(url)); | |
574 tag.setName("img"); | |
575 } | |
576 } | |
577 } | |
578 | |
579 static Map<String,String> getFileInfo(List<Object> list,Message.Source src) { | |
580 Map<String,String> info = new HashMap<String,String>(); | |
581 for( Object obj : list ) { | |
582 if( !(obj instanceof HtmlTag) ) | |
583 continue; | |
584 HtmlTag tag = (HtmlTag)obj; | |
585 String tagName = tag.getName().toLowerCase(); | |
586 if( tagName.equals("nabble_a") ) { | |
587 String filename = HtmlTag.unquote(tag.getAttributeValue("href")); | |
588 if( filename==null ) | |
589 continue; | |
590 String url = getUrl(filename,src); | |
591 info.put(filename,url); | |
592 } else if( tagName.equals("nabble_img") ) { | |
593 String filename = HtmlTag.unquote(tag.getAttributeValue("src")); | |
594 if( filename==null ) | |
595 continue; | |
596 String url = getUrl(filename,src); | |
597 info.put(filename,url); | |
598 } | |
599 } | |
600 return info; | |
601 } | |
602 | |
603 static String getUrl(String filename,Message.Source src) { | |
604 return FileDownload.url(filename,src); | |
605 } | |
606 | |
607 public static void saveImage(BufferedImage image, String fileName, Message.Source src) | |
608 throws ModelException | |
609 { | |
610 try { | |
611 // First convert to byte array | |
612 ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
613 ImageIO.write(image, "png", baos); | |
614 final byte[] bytes = baos.toByteArray(); | |
615 | |
616 InputStreamFactory factory = new InputStreamFactory() { | |
617 public InputStream in() throws IOException { | |
618 return new ByteArrayInputStream(bytes); | |
619 } | |
620 }; | |
621 uploadFile2(bytes.length, fileName, src, true, factory); | |
622 } catch(IOException e) { | |
623 throw ModelException.newInstance("file_io_exception",e); | |
624 } | |
625 } | |
626 | |
627 public static void saveFile(final byte[] contents, String fileName, Message.Source src) | |
628 throws ModelException | |
629 { | |
630 saveFile(contents, fileName, src, true); | |
631 } | |
632 | |
633 public static void saveFile(final byte[] contents, String fileName, Message.Source src, boolean checkSize) | |
634 throws ModelException | |
635 { | |
636 try { | |
637 InputStreamFactory factory = new InputStreamFactory() { | |
638 public InputStream in() throws IOException { | |
639 return new ByteArrayInputStream(contents); | |
640 } | |
641 }; | |
642 uploadFile2(contents.length, fileName, src, checkSize, factory); | |
643 } catch(IOException e) { | |
644 throw ModelException.newInstance("file_io_exception",e); | |
645 } | |
646 } | |
647 | |
648 | |
649 public static FileDetails[] getFiles(Message.Source src) { | |
650 return getFileDetails(src, null); | |
651 } | |
652 | |
653 public static final class UrlFileItem implements FileItem { | |
654 private final URL url; | |
655 | |
656 public UrlFileItem(URL url) { | |
657 this.url = url; | |
658 } | |
659 | |
660 public InputStream getInputStream() | |
661 throws IOException | |
662 { | |
663 try { | |
664 return url.openConnection().getInputStream(); | |
665 } catch(IllegalArgumentException e) { | |
666 logger.warn("",e); | |
667 throw new IOException(e.getMessage()); | |
668 } catch(RuntimeException e) { | |
669 logger.error("url = "+url,e); | |
670 throw e; | |
671 } | |
672 } | |
673 | |
674 public String getContentType() { | |
675 throw new UnsupportedOperationException(); | |
676 } | |
677 | |
678 public String getName() { | |
679 String s = url.getPath(); | |
680 int i = s.lastIndexOf('/'); | |
681 if( i != -1 ) | |
682 s = s.substring(i+1); | |
683 return s; | |
684 } | |
685 | |
686 public boolean isInMemory() { | |
687 return false; | |
688 } | |
689 | |
690 public long getSize() { | |
691 try { | |
692 long len = url.openConnection().getContentLength(); | |
693 if( len == -1 ) { | |
694 len = 0; | |
695 InputStream in = getInputStream(); | |
696 while(true) { | |
697 long n = in.skip(1000000L); | |
698 len += n; | |
699 if( n==0 ) { | |
700 if( in.read() == -1 ) | |
701 break; | |
702 len++; | |
703 } | |
704 } | |
705 in.close(); | |
706 } | |
707 return len; | |
708 } catch(IOException e) { | |
709 throw new RuntimeException(e); | |
710 } | |
711 } | |
712 | |
713 public byte[] get() { | |
714 throw new UnsupportedOperationException(); | |
715 } | |
716 | |
717 public java.lang.String getString(java.lang.String encoding) | |
718 throws java.io.UnsupportedEncodingException | |
719 { | |
720 throw new UnsupportedOperationException(); | |
721 } | |
722 | |
723 public java.lang.String getString() { | |
724 throw new UnsupportedOperationException(); | |
725 } | |
726 | |
727 public void write(java.io.File file) | |
728 throws java.lang.Exception | |
729 { | |
730 throw new UnsupportedOperationException(); | |
731 } | |
732 | |
733 public void delete() { | |
734 throw new UnsupportedOperationException(); | |
735 } | |
736 | |
737 public java.lang.String getFieldName() { | |
738 throw new UnsupportedOperationException(); | |
739 } | |
740 | |
741 public void setFieldName(java.lang.String name) { | |
742 throw new UnsupportedOperationException(); | |
743 } | |
744 | |
745 public boolean isFormField() { | |
746 return false; | |
747 } | |
748 | |
749 public void setFormField(boolean state) { | |
750 throw new UnsupportedOperationException(); | |
751 } | |
752 | |
753 public java.io.OutputStream getOutputStream() | |
754 throws java.io.IOException | |
755 { | |
756 throw new UnsupportedOperationException(); | |
757 } | |
758 | |
759 public FileItemHeaders getHeaders() { | |
760 throw new UnsupportedOperationException(); | |
761 } | |
762 | |
763 public void setHeaders(FileItemHeaders fileItemHeaders) { | |
764 throw new UnsupportedOperationException(); | |
765 } | |
766 | |
767 public String toString() { | |
768 return "UrlFileItem-"+url; | |
769 } | |
770 } | |
771 | |
772 | |
773 | |
774 static void nop() {} | |
775 | |
776 private FileUpload() {} // never | |
777 } |