/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.aimluck.eip.blog; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import javax.imageio.ImageIO; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import org.apache.turbine.util.RunData; import org.apache.velocity.context.Context; import com.aimluck.commons.field.ALDateTimeField; import com.aimluck.commons.field.ALNumberField; import com.aimluck.commons.field.ALStringField; import com.aimluck.eip.blog.util.BlogUtils; import com.aimluck.eip.cayenne.om.portlet.EipTBlog; import com.aimluck.eip.cayenne.om.portlet.EipTBlogEntry; import com.aimluck.eip.cayenne.om.portlet.EipTBlogFile; import com.aimluck.eip.cayenne.om.portlet.EipTBlogThema; import com.aimluck.eip.common.ALAbstractFormData; import com.aimluck.eip.common.ALDBErrorException; import com.aimluck.eip.common.ALEipConstants; import com.aimluck.eip.common.ALEipManager; import com.aimluck.eip.common.ALEipUser; import com.aimluck.eip.common.ALFileNotRemovedException; import com.aimluck.eip.common.ALPageNotFoundException; import com.aimluck.eip.fileupload.beans.FileuploadLiteBean; import com.aimluck.eip.fileupload.util.FileuploadUtils; import com.aimluck.eip.fileupload.util.FileuploadUtils.ShrinkImageSet; import com.aimluck.eip.modules.actions.common.ALAction; import com.aimluck.eip.orm.Database; import com.aimluck.eip.orm.query.SelectQuery; import com.aimluck.eip.services.accessctl.ALAccessControlConstants; import com.aimluck.eip.services.eventlog.ALEventlogConstants; import com.aimluck.eip.services.eventlog.ALEventlogFactoryService; import com.aimluck.eip.services.storage.ALStorageService; import com.aimluck.eip.timeline.util.TimelineUtils; import com.aimluck.eip.util.ALEipUtils; import com.aimluck.eip.util.ALLocalizationUtils; /** * ブログエントリーのフォームデータを管理するクラスです。 <BR> * */ public class BlogEntryFormData extends ALAbstractFormData { /** logger */ private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(BlogEntryFormData.class.getName()); /** Title */ private ALStringField title; /** メモ */ private ALStringField note; /** ブログ ID */ private ALNumberField blog_id; /** カテゴリID */ private ALNumberField thema_id; /** コメント付加フラグ */ private ALStringField allow_comments; /** 日時 */ private ALDateTimeField create_date; private List<BlogThemaResultData> themaList; /** */ private boolean is_new_thema; /** 添付ファイルリスト */ private List<FileuploadLiteBean> fileuploadList = null; /** 添付フォルダ名 */ private String folderName = null; private int uid; private String user_name; private boolean has_photo; private EipTBlog blog; private EipTBlogThema thema; private BlogThemaFormData blogthema; private String orgId; /** アクセス権限の機能名 */ private String aclPortletFeature = null; /** * * @param action * @param rundata * @param context * * */ @Override public void init(ALAction action, RunData rundata, Context context) throws ALPageNotFoundException, ALDBErrorException { super.init(action, rundata, context); is_new_thema = rundata.getParameters().getBoolean("is_new_thema"); uid = ALEipUtils.getUserId(rundata); orgId = Database.getDomainName(); folderName = rundata.getParameters().getString("folderName"); // 顔写真の取得 ALEipUser user = ALEipManager.getInstance().getUser(uid); user_name = user.getAliasName().getValue(); has_photo = user.hasPhoto(); int view_uid = BlogUtils.getViewId(rundata, context, uid); // アクセス権 if (view_uid == uid) { aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_BLOG_ENTRY_SELF; } else { aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_BLOG_ENTRY_OTHER; } } /** * 各フィールドを初期化します。 <BR> * * */ @Override public void initField() { // 更新日時 create_date = new ALDateTimeField(BlogUtils.DATE_TIME_FORMAT); create_date.setFieldName(ALLocalizationUtils.getl10n("BLOG_DAY_HOUR")); // Title title = new ALStringField(); title.setFieldName(ALLocalizationUtils.getl10n("BLOG_TITLE")); title.setTrim(true); // メモ note = new ALStringField(); note.setFieldName(ALLocalizationUtils.getl10n("BLOG_ENTRY")); note.setTrim(false); // ブログID blog_id = new ALNumberField(); blog_id.setFieldName(ALLocalizationUtils.getl10n("BLOG_BLOG")); // カテゴリID thema_id = new ALNumberField(); thema_id.setFieldName(ALLocalizationUtils.getl10n("BLOG_THEME")); // 公開区分 allow_comments = new ALStringField(); allow_comments.setFieldName(ALLocalizationUtils .getl10n("BLOG_ALLOW_COMMENT")); allow_comments.setValue("T"); allow_comments.setTrim(true); fileuploadList = new ArrayList<FileuploadLiteBean>(); blogthema = new BlogThemaFormData(); blogthema.initField(); } /** * * @param rundata * @param context */ public void loadThemaList(RunData rundata, Context context) { themaList = BlogUtils.getThemaList(rundata, context); } /** * エントリーの各フィールドに対する制約条件を設定します。 <BR> * * */ @Override protected void setValidator() { // 日付必須項目 create_date.setNotNull(true); // Title必須項目 title.setNotNull(true); // Titleの文字数制限 title.limitMaxLength(50); // メモの文字数制限 note.limitMaxLength(10000); blogthema.setValidator(); } /** * エントリーのフォームに入力されたデータの妥当性検証を行います。 <BR> * * @param msgList * @return TRUE 成功 FALSE 失敗 * */ @Override protected boolean validate(List<String> msgList) { // 日付 create_date.validate(msgList); // Title title.validate(msgList); // メモ note.validate(msgList); if (is_new_thema) { // テーマ blogthema.setMode(ALEipConstants.MODE_INSERT); blogthema.validate(msgList); } return (msgList.size() == 0); } /** * エントリーをデータベースから読み出します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean loadFormData(RunData rundata, Context context, List<String> msgList) { try { // オブジェクトモデルを取得 EipTBlogEntry entry = BlogUtils.getEipTBlogEntry(rundata, context); if (entry == null) { return false; } // 日時 create_date.setValue(entry.getCreateDate()); // Title title.setValue(entry.getTitle()); // メモ note.setValue(entry.getNote()); // カテゴリID thema_id.setValue(entry.getEipTBlogThema().getThemaId().longValue()); // 状態 allow_comments.setValue(entry.getAllowComments()); SelectQuery<EipTBlogFile> filequery = Database.query(EipTBlogFile.class); Expression fileexp = ExpressionFactory.matchDbExp(EipTBlogFile.EIP_TBLOG_ENTRY_PROPERTY + "." + EipTBlogEntry.ENTRY_ID_PK_COLUMN, entry.getEntryId()); filequery.setQualifier(fileexp); List<EipTBlogFile> files = filequery.fetchList(); FileuploadLiteBean filebean = null; int size = files.size(); for (int i = 0; i < size; i++) { EipTBlogFile file = files.get(i); filebean = new FileuploadLiteBean(); filebean.initField(); filebean.setFolderName(BlogUtils.PREFIX_DBFILE + Integer.toString(file.getFileId())); filebean.setFileName(file.getTitle()); filebean.setFileId(file.getFileId()); fileuploadList.add(filebean); } } catch (Exception ex) { logger.error("BlogEntryFormData.loadFormData", ex); return false; } return true; } /** * エントリーをデータベースから削除します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean deleteFormData(RunData rundata, Context context, List<String> msgList) { try { // オブジェクトモデルを取得 EipTBlogEntry entry = BlogUtils.getEipTBlogEntry(rundata, context); if (entry == null) { return false; } // entityIdの取得 int entityId = entry.getEntryId(); // タイトルの取得 String todoName = entry.getTitle(); int userId = ALEipUtils.getTurbineUser(entry.getOwnerId()).getUserId(); List<String> fpaths = new ArrayList<String>(); List<?> files = entry.getEipTBlogFiles(); if (files != null && files.size() > 0) { int size = files.size(); for (int i = 0; i < size; i++) { fpaths.add(((EipTBlogFile) files.get(i)).getFilePath()); } BlogUtils.deleteFiles(entityId, orgId, userId, fpaths); } // エントリーを削除 Database.delete(entry); Database.commit(); TimelineUtils.deleteTimelineActivity(rundata, context, "blog", entry .getEntryId() .toString()); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( entityId, ALEventlogConstants.PORTLET_TYPE_BLOG_ENTRY, todoName); } catch (ALFileNotRemovedException fe) { Database.rollback(); logger.error("BlogEntryFormData.deleteFormData", fe); msgList.add(ALLocalizationUtils.getl10n("ERROR_FILE_DETELE_FAILURE")); return false; } catch (Exception ex) { Database.rollback(); logger.error("BlogEntryFormData.deleteFormData", ex); return false; } return true; } /** * エントリーをデータベースに格納します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean insertFormData(RunData rundata, Context context, List<String> msgList) { boolean res = true; try { if (is_new_thema) { // テーマの登録処理 res = blogthema.insertFormData(rundata, context, msgList); if (res) { thema_id.setValue(blogthema.getThemaId()); } } if (res) { thema = Database.get(EipTBlogThema.class, Integer.valueOf((int) thema_id .getValue())); blog = BlogUtils.getEipTBlog(rundata, context); if (blog == null) { if (!insertBlogData(rundata, context)) { } } else { blog_id.setValue(blog.getBlogId().longValue()); } // 新規オブジェクトモデル EipTBlogEntry entry = Database.create(EipTBlogEntry.class); // Owner ID entry.setOwnerId(Integer.valueOf(uid)); // Title entry.setTitle(title.getValue()); // Note entry.setNote(note.getValue()); // ブログID entry.setEipTBlog(blog); // テーマID entry.setEipTBlogThema(thema); // コメント付加フラグ entry.setAllowComments("T"); // 作成日 entry.setCreateDate(create_date.getValue()); // 更新日 entry.setUpdateDate(Calendar.getInstance().getTime()); // 添付ファイルを登録する. insertAttachmentFiles(fileuploadList, folderName, uid, entry, msgList); Database.commit(); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( blog.getBlogId(), ALEventlogConstants.PORTLET_TYPE_BLOG_ENTRY, title.getValue()); // アクティビティ String loginName = ALEipUtils.getALEipUser(uid).getName().getValue(); int loginId = ALEipUtils.getALEipUser(uid).getUserId().getValueWithInt(); BlogUtils.createNewBlogActivity(entry, loginName, loginId, true); } } catch (Exception ex) { Database.rollback(); logger.error("BlogEntryFormData.insertFormData", ex); return false; } return res; } private List<Integer> getRequestedHasFileIdList( List<FileuploadLiteBean> attachmentFileNameList) { List<Integer> idlist = new ArrayList<Integer>(); FileuploadLiteBean filebean = null; // if (attachmentFileNameList != null && !"".equals(attachmentFileNameList)) // { if (attachmentFileNameList != null) { int size = attachmentFileNameList.size(); for (int i = 0; i < size; i++) { filebean = attachmentFileNameList.get(i); if (!filebean.isNewFile()) { int index = filebean.getFileId(); idlist.add(Integer.valueOf(index)); } } } return idlist; } private boolean insertAttachmentFiles( List<FileuploadLiteBean> fileuploadList, String folderName, int uid, EipTBlogEntry entry, List<String> msgList) { if (fileuploadList == null || fileuploadList.size() <= 0) { return true; } try { int length = fileuploadList.size(); ArrayList<FileuploadLiteBean> newfilebeans = new ArrayList<FileuploadLiteBean>(); FileuploadLiteBean filebean = null; for (int i = 0; i < length; i++) { filebean = fileuploadList.get(i); if (filebean.isNewFile()) { newfilebeans.add(filebean); } } int newfilebeansSize = newfilebeans.size(); if (newfilebeansSize > 0) { FileuploadLiteBean newfilebean = null; for (int j = 0; j < newfilebeansSize; j++) { newfilebean = newfilebeans.get(j); // サムネイル処理 String[] acceptExts = ImageIO.getWriterFormatNames(); ShrinkImageSet shrinkImageSet = FileuploadUtils.getBytesShrinkFilebean( orgId, folderName, uid, newfilebean, acceptExts, FileuploadUtils.DEF_THUMBNAIL_WIDTH, FileuploadUtils.DEF_THUMBNAIL_HEIGHT, msgList, true); String filename = j + "_" + String.valueOf(System.nanoTime()); // 新規オブジェクトモデル EipTBlogFile file = Database.create(EipTBlogFile.class); file.setOwnerId(Integer.valueOf(uid)); file.setTitle(newfilebean.getFileName()); file.setFilePath(BlogUtils.getRelativePath(filename)); if (shrinkImageSet != null && shrinkImageSet.getShrinkImage() != null) { file.setFileThumbnail(shrinkImageSet.getShrinkImage()); } file.setEipTBlogEntry(entry); file.setCreateDate(Calendar.getInstance().getTime()); file.setUpdateDate(Calendar.getInstance().getTime()); if (shrinkImageSet != null && shrinkImageSet.getFixImage() != null) { // ファイルの作成 ALStorageService.createNewFile(new ByteArrayInputStream( shrinkImageSet.getFixImage()), BlogUtils.FOLDER_FILEDIR_BLOG + ALStorageService.separator() + Database.getDomainName() + ALStorageService.separator() + BlogUtils.CATEGORY_KEY + ALStorageService.separator() + uid + ALStorageService.separator() + filename); } else { // ファイルの移動 ALStorageService.copyTmpFile( uid, folderName, String.valueOf(newfilebean.getFileId()), BlogUtils.FOLDER_FILEDIR_BLOG, BlogUtils.CATEGORY_KEY + ALStorageService.separator() + uid, filename); } } // 添付ファイル保存先のフォルダを削除 ALStorageService.deleteTmpFolder(uid, folderName); } } catch (Exception e) { logger.error("BlogEntryFormData.insertAttachmentFiles", e); } return true; } private boolean insertBlogData(RunData rundata, Context context) { try { // 新規オブジェクトモデル blog = Database.create(EipTBlog.class); // ユーザーID blog.setOwnerId(Integer.valueOf(uid)); // 作成日 blog.setCreateDate(Calendar.getInstance().getTime()); // 更新日 blog.setUpdateDate(Calendar.getInstance().getTime()); // ブログを登録 Database.commit(); // ブログIDの設定 blog_id.setValue(blog.getBlogId().longValue()); } catch (Exception ex) { Database.rollback(); logger.error("BlogEntryFormData.", ex); return false; } return true; } /** * データベースに格納されているエントリーを更新します。 <BR> * * @param rundata * @param context * @param msgList * @return TRUE 成功 FALSE 失敗 */ @Override protected boolean updateFormData(RunData rundata, Context context, List<String> msgList) { boolean res = false; try { // オブジェクトモデルを取得 EipTBlogEntry entry = BlogUtils.getEipTBlogEntry(rundata, context); if (entry == null) { return false; } if (is_new_thema) { // テーマの登録処理 res = blogthema.insertFormData(rundata, context, msgList); if (res) { thema = BlogUtils.getEipTBlogThema((long) blogthema.getThemaId()); thema_id.setValue(thema.getThemaId().longValue()); } } else { thema = Database.get(EipTBlogThema.class, Integer.valueOf((int) thema_id .getValue())); res = true; } if (res) { // Title entry.setTitle(title.getValue()); // メモ entry.setNote(note.getValue()); // カテゴリID entry.setEipTBlogThema(thema); // コメント付加フラグ entry.setAllowComments("T"); // 作成日 entry.setCreateDate(create_date.getValue()); // 更新日 entry.setUpdateDate(Calendar.getInstance().getTime()); // サーバーに残すファイルのID List<Integer> attIdList = getRequestedHasFileIdList(fileuploadList); // 現在選択しているエントリが持っているファイル List<EipTBlogFile> files = BlogUtils.getEipTBlogFileList(entry.getEntryId()); if (files != null) { int size = files.size(); for (int i = 0; i < size; i++) { EipTBlogFile file = files.get(i); if (!attIdList.contains(file.getFileId())) { // ファイルシステムから削除 ALStorageService.deleteFile(BlogUtils.getSaveDirPath(orgId, uid) + file.getFilePath()); // DBから削除 Database.delete(file); } } } // 添付ファイルを登録する. insertAttachmentFiles(fileuploadList, folderName, uid, entry, msgList); Database.commit(); // アクティビティ String loginName = ALEipUtils.getALEipUser(uid).getName().getValue(); int loginId = ALEipUtils.getALEipUser(uid).getUserId().getValueWithInt(); BlogUtils.createNewBlogActivity(entry, loginName, loginId, false); // イベントログに保存 ALEventlogFactoryService.getInstance().getEventlogHandler().log( entry.getEntryId(), ALEventlogConstants.PORTLET_TYPE_BLOG_ENTRY, title.getValue()); } } catch (Exception ex) { Database.rollback(); logger.error("BlogEntryFormData.", ex); return false; } return res; } /** * * @param rundata * @param context * @param msgList * @return * @throws ALPageNotFoundException * @throws ALDBErrorException */ @Override protected boolean setFormData(RunData rundata, Context context, List<String> msgList) throws ALPageNotFoundException, ALDBErrorException { // 日時 if (create_date.toString().equals("")) { create_date.setValue(Calendar.getInstance().getTime()); } boolean res = super.setFormData(rundata, context, msgList); if (res) { try { blogthema.setFormData(rundata, context, msgList); fileuploadList = BlogUtils.getFileuploadList(rundata); } catch (Exception ex) { logger.error("BlogEntryFormData.", ex); } } return res; } /** * カテゴリIDを取得します。 <BR> * * @return */ public ALNumberField getThemaId() { return thema_id; } /** * メモを取得します。 <BR> * * @return */ public ALStringField getNote() { return note; } /** * Title を取得します。 <BR> * * @return */ public ALStringField getTitle() { return title; } /** * @return */ public ALDateTimeField getCreateDate() { return create_date; } /** * カテゴリ一覧を取得します。 <BR> * * @return */ public List<BlogThemaResultData> getThemaList() { return themaList; } /** * @return */ public boolean isNewThema() { return is_new_thema; } /** * テーマを取得します。 * * @return */ public BlogThemaFormData getBlogThema() { return blogthema; } public List<FileuploadLiteBean> getAttachmentFileNameList() { return fileuploadList; } public String getFolderName() { return folderName; } public int getUserId() { return uid; } public String getUserName() { return user_name; } public boolean hasPhoto() { return has_photo; } /** * アクセス権限チェック用メソッド。<br /> * アクセス権限の機能名を返します。 * * @return */ @Override public String getAclPortletFeature() { return aclPortletFeature; } public void setThemaId(long i) { thema_id.setValue(i); } }