AttachmentManagerかと思いきや、それを単純に使っただけではどうもよろしくない。
どうよろしくないかというと、
public static void attachFile(AttachmentManager am, ContentEntityObject page, String temp_file_path, String fileName, String comment) throws FileNotFoundException, IOException, AttachmentDataExistsException { Attachment a; String mimetype; // String temp_file_path = File temp_file = new File(temp_file_path); MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap(); mimetype = mimetypesFileTypeMap.getContentType(temp_file); a = new Attachment(temp_file_path, mimetype, temp_file.length(), comment); a.setContent(page); a.setFileName(fileName); a.setVersion(1); am.saveAttachment(a, null, new FileInputStream(temp_file)); am.setAttachmentData(a, new FileInputStream(temp_file)); // throw new Exception("File ["+temp_file_path + "] not Found.("+ex.getLocalizedMessage()+")" ); }
みたいなメソッドを作ったのだけど、どうもうまくいかない。
いや、ファイルはアップロードされて登録されるのだけど、
どうもページのこの数字が
増えない。
ということでソースコード検索
普通のアップロード方法のActionから追っていった。AttachmentManagerを直接つかうのではないっポイ。見つけたのが
confluence-core/confluence/src/java/com/atlassian/confluence/pages/DefaultFileUploadManager.java
の
private void storeResources(List<StorableResource> storableResources, ContentEntityObject ceo) { List<SavableAttachment> saveableAttachments = new ArrayList<SavableAttachment>(); for (StorableResource storableResource : storableResources) { Attachment attachment = attachmentManager.getAttachment(ceo, storableResource.filename); Attachment previousVersion = null; if (attachment == null) { attachment = new Attachment(); } else { try { previousVersion = (Attachment) attachment.clone(); } catch (CloneNotSupportedException e) { throw new InfrastructureException(e); } } // attachment.setContentType(StringUtils.isBlank(contentType) ? OCTET_STREAM_MIME_TYPE : contentType); attachment.setContentType(mimeTypeTranslator.resolveMimeType(storableResource.filename, storableResource.contentType)); // if previous version exists, we want to preserve the case of the older version and disregard the new case of the newer version // if the user wants to change the case they can rename the attachment manually and allow the code invoked then to handle the required refactoring/renaming of links to this attachment if (previousVersion != null) attachment.setFileName(previousVersion.getFileName()); else attachment.setFileName(storableResource.filename); attachment.setComment(storableResource.comment); attachment.setFileSize(storableResource.contentLength); ceo.addAttachment(attachment); InputStream resourceStream; try { resourceStream = storableResource.resource.getInputStream(); } catch (IOException e) { throw new RuntimeException("Error opening input stream from resource: " + storableResource.resource, e); } saveableAttachments.add(new SavableAttachment(attachment, previousVersion, resourceStream)); } try { attachmentManager.saveAttachments(saveableAttachments); } catch (IOException e) { throw new RuntimeException(e); } finally { for (SavableAttachment attachment : saveableAttachments) { IOUtils.closeQuietly(attachment.getAttachmentData()); } } }
ポイントになるのは、
- attachmentManager.getAttachment(ceo, storableResource.filename);で前のバージョンを採ってきている。つまりファイル名でしか確認していない。
で、コンテントタイプ、ファイル名、コメント、ファイルサイズを設定して、
attachment.setContentType();
attachment.setFileName();
attachment.setComment();
attachment.setFileSize();
// ceo => ContentEntityObject(pageObjectでも)
ceo.addAttachment(attachment);
ContentEntityObjectでaddAttachmentしている。
このaddAttachmentで、ContentEntityObjectとAttachmentの双方にお互いのリンクポインタを設定している。実装は
confluence-core/confluence/src/java/com/atlassian/confluence/core/ContentEntityObject.java
public void addAttachment(Attachment attachment) { getAttachments().add(attachment); attachment.setContent(this); }
SavableAttachment にいったんキャッシュ
いったんSavableAttachmentオブジェクトとして保管。このオブジェクトは保存時に必要な3つの引数を保存しているだけ。
confluence-core/confluence/src/java/com/atlassian/confluence/pages/SavableAttachment.java
AttachmentManager.saveAttachmentsが本丸
confluence-core/confluence/src/java/com/atlassian/confluence/pages/DefaultAttachmentManager.java
結局メインは、saveAttachmentsメソッド。
attachmentManager.saveAttachmentはショートカット。
上記のコードは page.addAttachment(a) というのがないためにAttachmentにContentEntityObjectを結び付けられてなかった。
おそらくそれでこの辺りのコードがFireしてなかったのではないかな?
//Finally, fire batch completed event eventManager.publishEvent(new AttachmentBatchUploadCompletedEvent(this, attachments));