日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Liferay 控制面板在指定文件夹添加Basic Document流程分析

發(fā)布時(shí)間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Liferay 控制面板在指定文件夹添加Basic Document流程分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

結(jié)論:

當(dāng)在Liferay中用管理員登錄,導(dǎo)航到控制面板->Documents and Media ,在指定文件夾下添加BasicDocument時(shí),服務(wù)器做了如下的事情:

(1) 在DLFILEENTRY表中添加一條記錄代表被添加的文檔。

(2) 在DLFILEENTRYVERSION表中添加一條記錄,通過fileEntryId外鍵關(guān)聯(lián)到DLFILEENTRY表,用來記錄剛被添加文檔的版本信息。

(3)?在DLFOLDER表中更新最新post提交的時(shí)間戳。

(4) 根據(jù)服務(wù)器對于com.liferay.portlet.documentlibrary.store的具體實(shí)現(xiàn)的不同,先對文件進(jìn)行病毒掃描(在portal.properties 中有開關(guān)),然后把上傳的資源文件存入到Store的某個(gè)具體位置。

Store有5種實(shí)現(xiàn),我至少可以保證,如果用的是FileSystemStore,那么這個(gè)資源文件被放入$liferay_home/data/document_library目錄,并且最終文件名不再是上傳的文件名,而是<version_number>.如果使用的是DBStore,那么這個(gè)資源文件最終會(huì)被放在數(shù)據(jù)庫中DLCONTENT表中,并且資源文件(比如圖片)以BLOB的形式存儲(chǔ)。

(5)在ASSETENTRY表中添加一條記錄,它通過classpk外鍵關(guān)聯(lián)到DLFILEENTRY,因?yàn)镕ile也是一種資產(chǎn),所以必須在這張表中也留下記錄。

?

?

具體分析:

?Liferay控制面板中,當(dāng)創(chuàng)建了文件夾,然后要在其中添加某個(gè)Basic Document:

?

查看瀏覽器debug信息:

可以發(fā)現(xiàn),它調(diào)用的struts_action/document_library/edit_file_entry

?

我們?nèi)?strong>struts-config.xml中去找:

  • <action?path="/document_library/edit_file_entry"?type="com.liferay.portlet.documentlibrary.action.EditFileEntryAction">?
  • ????????????<forward?name="portlet.document_library.edit_file_entry"?path="portlet.document_library.edit_file_entry"?/>?
  • ????????????<forward?name="portlet.document_library.error"?path="portlet.document_library.error"?/>?
  • ????????</action>?
  • 可以發(fā)現(xiàn), 它會(huì)forwardportlet.document_library.edit_file_entry的路徑名下找頁面:

    我們?nèi)?strong>tiles-def.xml中找匹配:

  • <definition?name="portlet.document_library.edit_file_entry"?extends="portlet.document_library">?
  • ????????<put?name="portlet_content"?value="/portlet/document_library/edit_file_entry.jsp"?/>?
  • ????</definition>?
  • ?

    所以,它最終會(huì)訪問/portlet/document_library/edit_file_entry.jsp頁面:

    這個(gè)頁面會(huì)吧你剛才選擇的目錄列出來,比如我們剛才選擇了abcde目錄,那么在這里,它就會(huì)顯示出來:

    對應(yīng)的顯示代碼是

  • <aui:field-wrapper?label="folder">?
  • ????????????<aui:a?href="<%=?viewFolderURL?%>"?id="folderName"><%=?folderName?%></aui:a>?
  • ?
  • ????????????<c:if?test="<%=?referringPortletResourceRootPortletId.equals(PortletKeys.ASSET_PUBLISHER)?%>">?
  • ????????????????<aui:button?name="openFolderSelectorButton"?onClick='<%=?renderResponse.getNamespace()?+?"openFolderSelector();"?%>'?value="select"?/>?
  • ?
  • ????????????????<%?
  • ????????????????String?taglibRemoveFolder?=?"Liferay.Util.removeFolderSelection('folderId',?'folderName',?'"?+?renderResponse.getNamespace()?+?"');";?
  • ????????????????%>?
  • ?
  • ????????????????<aui:button?disabled="<%=?folderId?<=?0?%>"?name="removeFolderButton"?onClick="<%=?taglibRemoveFolder?%>"?value="remove"?/>?
  • ????????????</c:if>?
  • ????????</aui:field-wrapper>?

  • 然后,它會(huì)有一個(gè)文件上傳框:

  • <aui:input?name="file"?type="file">?
  • ????????????<aui:validator?name="acceptFiles">?
  • ????????????????'<%=?StringUtil.merge(PrefsPropsUtil.getStringArray(PropsKeys.DL_FILE_EXTENSIONS,?StringPool.COMMA))?%>'?
  • ????????????</aui:validator>?
  • ????????</aui:input>?
  • 它會(huì)通過aui框架的校驗(yàn)器來校驗(yàn)被上傳的文件擴(kuò)展名和大小。

    輸入文件標(biāo)題和正文的部分我就略過了,不是重點(diǎn),我們現(xiàn)在想關(guān)注的是,到底當(dāng)點(diǎn)擊最下方的"Publish"按鈕時(shí)發(fā)生了什么。

    ?

    深入分析點(diǎn)擊"Publish"按鈕后發(fā)生的事情

    對應(yīng)的代碼是:

  • <aui:button?disabled="<%=?checkedOut?&&?!hasLock?||?(pending?&&?PropsValues.DL_FILE_ENTRY_DRAFTS_ENABLED)?%>"?name="publishButton"?type="submit"?value="<%=?publishButtonLabel?%>"?/>?

  • 它會(huì)吧整個(gè)表單提交,對應(yīng)代碼是:

  • <aui:form?action="<%=?editFileEntryURL?%>"?cssClass="lfr-dynamic-form"?enctype="multipart/form-data"?method="post"?name="fm"?onSubmit='<%=?"event.preventDefault();?"?+?renderResponse.getNamespace()?+?"saveFileEntry(false);"?%>'>?
  • ????<aui:input?name="<%=?Constants.CMD?%>"?type="hidden"?/>?
  • ????<aui:input?name="redirect"?type="hidden"?value="<%=?redirect?%>"?/>?
  • ????<aui:input?name="backURL"?type="hidden"?value="<%=?backURL?%>"?/>?
  • ????<aui:input?name="referringPortletResource"?type="hidden"?value="<%=?referringPortletResource?%>"?/>?
  • ????<aui:input?name="uploadProgressId"?type="hidden"?value="<%=?uploadProgressId?%>"?/>?
  • ????<aui:input?name="repositoryId"?type="hidden"?value="<%=?repositoryId?%>"?/>?
  • ????<aui:input?name="folderId"?type="hidden"?value="<%=?folderId?%>"?/>?
  • ????<aui:input?name="fileEntryId"?type="hidden"?value="<%=?fileEntryId?%>"?/>?
  • ????<aui:input?name="workflowAction"?type="hidden"?value="<%=?WorkflowConstants.ACTION_PUBLISH?%>"?/>?
  • ..?
  • 而因?yàn)橛胮ost提交,所以這些信息都在payload中:

  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_formDate"?
  • ?
  • 1341536588996?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_cmd"?
  • ?
  • add?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_redirect"?
  • ?
  • http://localhost:8080/group/control_panel/manage?p_p_id=20&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&doAsGroupId=19&refererPlid=12655&_20_refererPlid=12655&_20_doAsGroupId=19&_20_struts_action=%2Fdocument_library%2Fview&_20_folderId=16904?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_backURL"?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_referringPortletResource"?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_uploadProgressId"?
  • ?
  • dlFileEntryUploadProgress?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_repositoryId"?
  • ?
  • 19?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_folderId"?
  • ?
  • 16904?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_fileEntryId"?
  • ?
  • 0?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_workflowAction"?
  • ?
  • 1?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_file";?filename="charles_wang.jpg"?
  • Content-Type:?p_w_picpath/jpeg?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_title"?
  • ?
  • title?of?new?document?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_description"?
  • ?
  • a?new?document?which?contains?a?p_w_picpath?and?resides?in?abcde?folder?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_fileEntryTypeId"?
  • ?
  • 0?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_assetTagNames"?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_assetLinkSearchContainerPrimaryKeys"?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_assetLinkEntryIds"?
  • ?
  • ?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_inputPermissionsShowOptions"?
  • ?
  • false?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_inputPermissionsViewRole"?
  • ?
  • Guest?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_guestPermissions"?
  • ?
  • ADD_DISCUSSION?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_guestPermissions"?
  • ?
  • VIEW?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_groupPermissions"?
  • ?
  • ADD_DISCUSSION?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D?
  • Content-Disposition:?form-data;?name="_20_groupPermissions"?
  • ?
  • VIEW?
  • ------WebKitFormBoundaryHrjra277wXTqeY5D--?
  • 所以,action還是自身頁面,不難在struts-config.xml中找到Action類名為EditFileEntryAction

    因?yàn)槲覀兊腸md是add,所以它會(huì)走以下流程:

  • public?void?processAction(?
  • ????????????ActionMapping?mapping,?ActionForm?form,?PortletConfig?portletConfig,?
  • ????????????ActionRequest?actionRequest,?ActionResponse?actionResponse)?
  • ????????throws?Exception?{?
  • ?
  • ????????String?cmd?=?ParamUtil.getString(actionRequest,?Constants.CMD);?
  • ?
  • ????????..?
  • ????????????else?if?(cmd.equals(Constants.ADD)?||?cmd.equals(Constants.UPDATE)?
  • ????????????????||?cmd.equals(Constants.UPDATE_AND_CHECKIN))?{?
  • ?
  • ????????????????updateFileEntry(portletConfig,?actionRequest,?actionResponse);?
  • ????????????}?
  • ????????????..?
  • ?

    它會(huì)去調(diào)用updateFileEntry方法,這就是我們研究的重心:

  • protected?void?updateFileEntry(?
  • ????????????PortletConfig?portletConfig,?ActionRequest?actionRequest,?
  • ????????????ActionResponse?actionResponse)?
  • ????????throws?Exception?{?
  • ?
  • ????????UploadPortletRequest?uploadPortletRequest?=?
  • ????????????PortalUtil.getUploadPortletRequest(actionRequest);?
  • ?
  • ????????ThemeDisplay?themeDisplay?=?(ThemeDisplay)actionRequest.getAttribute(?
  • ????????????WebKeys.THEME_DISPLAY);?
  • ?
  • ????????String?cmd?=?ParamUtil.getString(uploadPortletRequest,?Constants.CMD);?
  • ?
  • ????????long?fileEntryId?=?ParamUtil.getLong(?
  • ????????????uploadPortletRequest,?"fileEntryId");?
  • ?
  • ????????long?repositoryId?=?ParamUtil.getLong(?
  • ????????????uploadPortletRequest,?"repositoryId");?
  • ????????long?folderId?=?ParamUtil.getLong(uploadPortletRequest,?"folderId");?
  • ????????String?sourceFileName?=?uploadPortletRequest.getFileName("file");?
  • ????????String?title?=?ParamUtil.getString(uploadPortletRequest,?"title");?
  • ????????String?description?=?ParamUtil.getString(?
  • ????????????uploadPortletRequest,?"description");?
  • ????????String?changeLog?=?ParamUtil.getString(?
  • ????????????uploadPortletRequest,?"changeLog");?
  • ????????boolean?majorVersion?=?ParamUtil.getBoolean(?
  • ????????????uploadPortletRequest,?"majorVersion");?
  • ?
  • ????????if?(folderId?>?0)?{?
  • ????????????Folder?folder?=?DLAppServiceUtil.getFolder(folderId);?
  • ?
  • ????????????if?(folder.getGroupId()?!=?themeDisplay.getScopeGroupId())?{?
  • ????????????????throw?new?NoSuchFolderException();?
  • ????????????}?
  • ????????}?
  • ?
  • ????????InputStream?inputStream?=?null;?
  • ?
  • ????????try?{?
  • ????????????String?contentType?=?uploadPortletRequest.getContentType("file");?
  • ?
  • ????????????long?size?=?uploadPortletRequest.getSize("file");?
  • ?
  • ????????????if?(cmd.equals(Constants.ADD)?&&?(size?==?0))?{?
  • ????????????????contentType?=?MimeTypesUtil.getContentType(title);?
  • ????????????}?
  • ?
  • ????????????if?(cmd.equals(Constants.ADD)?||?(size?>?0))?{?
  • ????????????????String?portletName?=?portletConfig.getPortletName();?
  • ?
  • ????????????????if?(portletName.equals(PortletKeys.MEDIA_GALLERY_DISPLAY))?{?
  • ????????????????????String?portletResource?=?ParamUtil.getString(?
  • ????????????????????????actionRequest,?"portletResource");?
  • ?
  • ????????????????????PortletPreferences?portletPreferences?=?null;?
  • ?
  • ????????????????????if?(Validator.isNotNull(portletResource))?{?
  • ????????????????????????PortletPreferencesFactoryUtil.getPortletSetup(?
  • ????????????????????????????actionRequest,?portletResource);?
  • ????????????????????}?
  • ????????????????????else?{?
  • ????????????????????????portletPreferences?=?actionRequest.getPreferences();?
  • ????????????????????}?
  • ?
  • ????????????????????String[]?mimeTypes?=?DLUtil.getMediaGalleryMimeTypes(?
  • ????????????????????????portletPreferences,?actionRequest);?
  • ?
  • ????????????????????if?(Arrays.binarySearch(mimeTypes,?contentType)?<?0)?{?
  • ????????????????????????throw?new?FileMimeTypeException(contentType);?
  • ????????????????????}?
  • ????????????????}?
  • ????????????}?
  • ?
  • ????????????inputStream?=?uploadPortletRequest.getFileAsStream("file");?
  • ?
  • ????????????ServiceContext?serviceContext?=?ServiceContextFactory.getInstance(?
  • ????????????????DLFileEntry.class.getName(),?actionRequest);?
  • ?
  • ????????????FileEntry?fileEntry?=?null;?
  • ?
  • ????????????if?(cmd.equals(Constants.ADD))?{?
  • ????????????????if?(Validator.isNull(title))?{?
  • ????????????????????title?=?sourceFileName;?
  • ????????????????}?
  • ?
  • ????????????????//?Add?file?entry?
  • ?
  • ????????????????fileEntry?=?DLAppServiceUtil.addFileEntry(?
  • ????????????????????repositoryId,?folderId,?sourceFileName,?contentType,?title,?
  • ????????????????????description,?changeLog,?inputStream,?size,?serviceContext);?
  • ?
  • ????????????????AssetPublisherUtil.addAndStoreSelection(?
  • ????????????????????actionRequest,?DLFileEntry.class.getName(),?
  • ????????????????????fileEntry.getFileEntryId(),?-1);?
  • ????????????}?
  • ????????????else?if?(cmd.equals(Constants.UPDATE_AND_CHECKIN))?{?
  • ?
  • ????????????????//?Update?file?entry?and?checkin?
  • ?
  • ????????????????fileEntry?=?DLAppServiceUtil.updateFileEntryAndCheckIn(?
  • ????????????????????fileEntryId,?sourceFileName,?contentType,?title,?
  • ????????????????????description,?changeLog,?majorVersion,?inputStream,?
  • ????????????????????size,?serviceContext);?
  • ????????????}?
  • ????????????else?{?
  • ?
  • ????????????????//?Update?file?entry?
  • ?
  • ????????????????fileEntry?=?DLAppServiceUtil.updateFileEntry(?
  • ????????????????????fileEntryId,?sourceFileName,?contentType,?title,?
  • ????????????????????description,?changeLog,?majorVersion,?inputStream,?
  • ????????????????????size,?serviceContext);?
  • ????????????}?
  • ?
  • ????????????AssetPublisherUtil.addRecentFolderId(?
  • ????????????????actionRequest,?DLFileEntry.class.getName(),?folderId);?
  • ????????}?
  • ????????finally?{?
  • ????????????StreamUtil.cleanUp(inputStream);?
  • ????????}?
  • ????}?
  • ?

    從第06-27行就是從post的請求的payload中獲取一些參數(shù)信息,然后第29行對folderId進(jìn)行判斷,因?yàn)槲覀兊?strong>folderId為19604,它大于0,所以第30行用DLAppServiceUtil的方法獲取這個(gè)folder的實(shí)例,它最終會(huì)調(diào)用DLFolderLocalServiceImplgetFolder(folderId)方法:

  • public?DLFolder?getFolder(long?folderId)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????return?dlFolderPersistence.findByPrimaryKey(folderId);?
  • ????}?
  • 這會(huì)發(fā)起一個(gè)數(shù)據(jù)庫的查詢,然后把查出來的結(jié)果封裝成DLFolder對象:

    從這里看出來,這個(gè)folder就是我們昨天創(chuàng)建的名字叫"abcde"的folder.

    ?

    然后從40行開始,正式對于這個(gè)文檔中的文件進(jìn)行操作。先從40-72行做一些信息提取工作,然后從74行開始正式上傳文件,因?yàn)槲覀兊腸md是“add",所以它會(huì)執(zhí)行86-95行,我們詳細(xì)分析:

    ?

    添加FileEntry:

    第88-90行最終會(huì)調(diào)用DLAppServiceImpl類的addFileEntry方法:

  • public?FileEntry?addFileEntry(?
  • ????????????long?repositoryId,?long?folderId,?String?sourceFileName,?
  • ????????????String?mimeType,?String?title,?String?description,?String?changeLog,?
  • ????????????InputStream?is,?long?size,?ServiceContext?serviceContext)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????if?(is?==?null)?{?
  • ????????????is?=?new?UnsyncByteArrayInputStream(new?byte[0]);?
  • ????????????size?=?0;?
  • ????????}?
  • ?
  • ????????Repository?repository?=?getRepository(repositoryId);?
  • ?
  • ????????FileEntry?fileEntry?=?repository.addFileEntry(?
  • ????????????folderId,?sourceFileName,?mimeType,?title,?description,?changeLog,?
  • ????????????is,?size,?serviceContext);?
  • ?
  • ????????dlAppHelperLocalService.addFileEntry(?
  • ????????????getUserId(),?fileEntry,?fileEntry.getFileVersion(),?serviceContext);?
  • ?
  • ????????return?fileEntry;?
  • ????}?
  • 它一共做了2件事情:

    ?

    事情1:

    第14行-15行,它最終會(huì)調(diào)用DLFileEntryLocalServiceImpl類的addFileEntry方法:

  • public?DLFileEntry?addFileEntry(?
  • ????????????long?userId,?long?groupId,?long?repositoryId,?long?folderId,?
  • ????????????String?sourceFileName,?String?mimeType,?String?title,?
  • ????????????String?description,?String?changeLog,?long?fileEntryTypeId,?
  • ????????????Map<String,?Fields>?fieldsMap,?File?file,?InputStream?is,?long?size,?
  • ????????????ServiceContext?serviceContext)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????if?((size?==?0)?&&?Validator.isNull(title))?{?
  • ????????????throw?new?FileNameException();?
  • ????????}?
  • ?
  • ????????//?File?entry?
  • ?
  • ????????User?user?=?userPersistence.findByPrimaryKey(userId);?
  • ????????folderId?=?dlFolderLocalService.getFolderId(?
  • ????????????user.getCompanyId(),?folderId);?
  • ????????String?name?=?String.valueOf(?
  • ????????????counterLocalService.increment(DLFileEntry.class.getName()));?
  • ????????String?extension?=?getExtension(title,?sourceFileName);?
  • ????????fileEntryTypeId?=?getFileEntryTypeId(?
  • ????????????DLUtil.getGroupIds(groupId),?folderId,?fileEntryTypeId);?
  • ????????Date?now?=?new?Date();?
  • ?
  • ????????validateFile(groupId,?folderId,?title,?extension,?file,?is);?
  • ?
  • ????????long?fileEntryId?=?counterLocalService.increment();?
  • ?
  • ????????DLFileEntry?dlFileEntry?=?dlFileEntryPersistence.create(fileEntryId);?
  • ?
  • ????????dlFileEntry.setUuid(serviceContext.getUuid());?
  • ????????dlFileEntry.setGroupId(groupId);?
  • ????????dlFileEntry.setCompanyId(user.getCompanyId());?
  • ????????dlFileEntry.setUserId(user.getUserId());?
  • ????????dlFileEntry.setUserName(user.getFullName());?
  • ????????dlFileEntry.setVersionUserId(user.getUserId());?
  • ????????dlFileEntry.setVersionUserName(user.getFullName());?
  • ????????dlFileEntry.setCreateDate(serviceContext.getCreateDate(now));?
  • ????????dlFileEntry.setModifiedDate(serviceContext.getModifiedDate(now));?
  • ????????dlFileEntry.setRepositoryId(repositoryId);?
  • ????????dlFileEntry.setFolderId(folderId);?
  • ????????dlFileEntry.setName(name);?
  • ????????dlFileEntry.setExtension(extension);?
  • ????????dlFileEntry.setMimeType(mimeType);?
  • ????????dlFileEntry.setTitle(title);?
  • ????????dlFileEntry.setDescription(description);?
  • ????????dlFileEntry.setFileEntryTypeId(fileEntryTypeId);?
  • ????????dlFileEntry.setVersion(DLFileEntryConstants.VERSION_DEFAULT);?
  • ????????dlFileEntry.setSize(size);?
  • ????????dlFileEntry.setReadCount(DLFileEntryConstants.DEFAULT_READ_COUNT);?
  • ?
  • ????????dlFileEntryPersistence.update(dlFileEntry,?false);?
  • ?
  • ????????//?File?version?
  • ?
  • ????????DLFileVersion?dlFileVersion?=?addFileVersion(?
  • ????????????user,?dlFileEntry,?serviceContext.getModifiedDate(now),?extension,?
  • ????????????mimeType,?title,?description,?null,?StringPool.BLANK,?
  • ????????????fileEntryTypeId,?fieldsMap,?DLFileEntryConstants.VERSION_DEFAULT,?
  • ????????????size,?WorkflowConstants.STATUS_DRAFT,?serviceContext);?
  • ?
  • ????????dlFileEntry.setFileVersion(dlFileVersion);?
  • ?
  • ????????//?Folder?
  • ?
  • ????????if?(folderId?!=?DLFolderConstants.DEFAULT_PARENT_FOLDER_ID)?{?
  • ????????????dlFolderLocalService.updateLastPostDate(?
  • ????????????????dlFileEntry.getFolderId(),?dlFileEntry.getModifiedDate());?
  • ????????}?
  • ?
  • ????????//?File?
  • ?
  • ????????if?(file?!=?null)?{?
  • ????????????DLStoreUtil.addFile(?
  • ????????????????user.getCompanyId(),?dlFileEntry.getDataRepositoryId(),?name,?
  • ????????????????false,?file);?
  • ????????}?
  • ????????else?{?
  • ????????????DLStoreUtil.addFile(?
  • ????????????????user.getCompanyId(),?dlFileEntry.getDataRepositoryId(),?name,?
  • ????????????????false,?is);?
  • ????????}?
  • ?
  • ????????return?dlFileEntry;?
  • ????}?
  • 所以,總結(jié)來說就是(13-52行)在DLFILEENTRY表中添加一條記錄,代表了我們剛創(chuàng)建的文件:

    然后(54-62行)在DLFILEVERSION表中添加一條記錄:

    然后(64-69行)在DLFOLDER表中更新最新post提交的時(shí)間戳:

    然后(73-82行)會(huì)添加這個(gè)我們被上傳的文件(比如 charles_wang.jpg), 如何添加呢?可以一直跟進(jìn)直到DLStoreImpl類的addFile方法:

  • public?void?addFile(?
  • ????????????long?companyId,?long?repositoryId,?String?fileName,?
  • ????????????boolean?validateFileExtension,?File?file)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????validate(fileName,?validateFileExtension,?file);?
  • ?
  • ????????if?(PropsValues.DL_STORE_ANTIVIRUS_ENABLED)?{?
  • ????????????AntivirusScannerUtil.scan(file);?
  • ????????}?
  • ?
  • ????????store.addFile(companyId,?repositoryId,?fileName,?file);?
  • ????}?
  • 它首先會(huì)判斷是否開啟了store的病毒掃描機(jī)制,這個(gè)變量定義在portal.properties文件中:

  • ???#?Set?this?property?to?true?to?enable?execution?of?antivirus?check?when?
  • ???#?files?are?submitted?into?a?store.?Setting?this?value?to?true?will?prevent?
  • ???#?any?potential?virus?files?from?entering?the?store?but?will?not?allow?for?
  • ???#?file?quarantines.?
  • ???#?
  • ???dl.store.antivirus.enabled=false?
  • 然后調(diào)用store的addFile方法,它會(huì)具體根據(jù)我們Store的實(shí)現(xiàn)來決定如何添加這個(gè)資源文件。

    ?那么我們的服務(wù)器上用的是什么樣的store呢?可以參見portal.properties中的定義:

  • #?
  • ???#?Set?the?name?of?a?class?that?implements?
  • ???#?com.liferay.portlet.documentlibrary.store.Store.?The?
  • ???#?document?library?server?will?use?this?to?persist?documents.?
  • ???#?
  • ???#dl.store.impl=com.liferay.portlet.documentlibrary.store.AdvancedFileSystemStore?
  • ???#dl.store.impl=com.liferay.portlet.documentlibrary.store.CMISStore?
  • ???#dl.store.impl=com.liferay.portlet.documentlibrary.store.DBStore?
  • ???dl.store.impl=com.liferay.portlet.documentlibrary.store.FileSystemStore?
  • ???#dl.store.impl=com.liferay.portlet.documentlibrary.store.JCRStore?
  • ???#dl.store.impl=com.liferay.portlet.documentlibrary.store.S3Store?
  • ?

    所以,我們會(huì)用FileSystemStore作為Store的實(shí)現(xiàn),這也是默認(rèn)的實(shí)現(xiàn)。

  • public?void?addFile(?
  • ????????????long?companyId,?long?repositoryId,?String?fileName,?InputStream?is)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????try?{?
  • ????????????File?fileNameVersionFile?=?getFileNameVersionFile(?
  • ????????????????companyId,?repositoryId,?fileName,?VERSION_DEFAULT);?
  • ?
  • ????????????if?(fileNameVersionFile.exists())?{?
  • ????????????????throw?new?DuplicateFileException(fileNameVersionFile.getPath());?
  • ????????????}?
  • ?
  • ????????????FileUtil.write(fileNameVersionFile,?is);?
  • ????????}?
  • ????????catch?(IOException?ioe)?{?
  • ????????????throw?new?SystemException(ioe);?
  • ????????}?
  • ????}?
  • 從調(diào)試信息上來看,它會(huì)先去獲取companyId,repositoryId,fileName等信息,最終File對象是服務(wù)器節(jié)點(diǎn)上一個(gè)帶版本號的url:

    而被上傳的文件也被蓋頭換面了,居然在$tomcat_home/temp目錄下,而且名字叫upload_000010.jpg,我們在這個(gè)目錄下找,是我們所要上傳的文件:

    ?

    所以,最終這個(gè)文件被保存到了D:\Liferay_Cluster_Enterprise\Node1\liferay-portal-tomcat-6.1.10-ee-ga1\liferay-portal-6.1.10-ee-ga1\data\document_library\1\16904\501 目錄下,并且文件名不再是charles_wang.png,而是就叫<version_number>.并且后面不帶擴(kuò)展名了。我們比較這charles_wang.png和這個(gè)1.0文件的大小,發(fā)現(xiàn)他們是一致的(都是153kb),所以這說明文件已經(jīng)被復(fù)制到了Liferay節(jié)點(diǎn)上。

    ?

    進(jìn)一步研究,如果不使用FileSystemStore會(huì)如何。我們在portal-ext.properties?dl.store.impl改為DBStore:

  • dl.store.impl=com.liferay.portlet.documentlibrary.store.DBStore?
  • 它會(huì)去調(diào)用DBStore類的addFile代碼,最終會(huì)調(diào)用DBStore類的updateFile代碼:

  • public?void?updateFile(?
  • ????????????long?companyId,?long?repositoryId,?String?fileName,?
  • ????????????String?versionLabel,?File?file)?
  • ????????throws?PortalException,?SystemException?{?
  • ?
  • ????????if?(DLContentLocalServiceUtil.hasContent(?
  • ????????????????companyId,?repositoryId,?fileName,?versionLabel))?{?
  • ?
  • ????????????throw?new?DuplicateFileException(fileName);?
  • ????????}?
  • ?
  • ????????InputStream?inputStream?=?null;?
  • ?
  • ????????try?{?
  • ?????????????inputStream?=?new?FileInputStream(file);?
  • ????????}?
  • ????????catch?(FileNotFoundException?fnfe)?{?
  • ????????????throw?new?SystemException(fnfe);?
  • ????????}?
  • ?
  • ????????DLContentLocalServiceUtil.addContent(?
  • ????????????companyId,?repositoryId,?fileName,?versionLabel,?inputStream,?
  • ????????????file.length());?
  • ????}?
  • 它最終會(huì)調(diào)用DLContentLocalServiceImpl的addContent方法:

  • public?DLContent?addContent(?
  • ????????????long?companyId,?long?repositoryId,?String?path,?String?version,?
  • ????????????InputStream?inputStream,?long?size)?
  • ????????throws?SystemException?{?
  • ?
  • ????????try?{?
  • ????????????long?contentId?=?counterLocalService.increment();?
  • ?
  • ????????????DLContent?dlContent?=?dlContentPersistence.create(contentId);?
  • ?
  • ????????????dlContent.setCompanyId(companyId);?
  • ????????????dlContent.setRepositoryId(repositoryId);?
  • ????????????dlContent.setPath(path);?
  • ????????????dlContent.setVersion(version);?
  • ?
  • ????????????OutputBlob?dataOutputBlob?=?new?OutputBlob(inputStream,?size);?
  • ?
  • ????????????dlContent.setData(dataOutputBlob);?
  • ?
  • ????????????dlContent.setSize(size);?
  • ?
  • ????????????dlContentPersistence.update(dlContent,?false);?
  • ?
  • ????????????return?dlContent;?
  • ????????}?
  • ????????finally?{?
  • ????????????StreamUtil.cleanUp(inputStream);?
  • ????????}?
  • ????}?
  • 從這里我們可以很清楚的看到,它會(huì)吧這個(gè)文件的內(nèi)容以Blob的形式保存,然后連同companyId,repositoryId,version等信息一起寫在DLCONTENT數(shù)據(jù)庫表中:

    我們復(fù)制上述動(dòng)作時(shí)候,不幸發(fā)生了如下的異常:

  • Caused?by:?java.lang.ClassCastException:?com.liferay.portal.kernel.dao.jdbc.OutputBlob?cannot?be?cast?to?oracle.sql.BLOB?
  • ????at?oracle.jdbc.driver.OraclePreparedStatement.setBlob(OraclePreparedStatement.java:6663)?
  • ????at?oracle.jdbc.driver.OraclePreparedStatementWrapper.setBlob(OraclePreparedStatementWrapper.java:128)?
  • 從http://issues.liferay.com/browse/LPS-26375上我找到了解決方法,就是修改portal-hbm.xml文件,然后把類型配置正確就可以了:

  • <class?name="com.liferay.portlet.documentlibrary.model.DLContentDataBlobModel"?table="DLContent"?lazy="true">?
  • ????????<id?name="contentId"?column="contentId">?
  • ????????????<generator?class="foreign">?
  • ????????????????<param?name="property">com.liferay.portlet.documentlibrary.model.impl.DLContentImpl</param>?
  • ????????????</generator>?
  • ????????</id>?
  • ????????<property?column="data_"?name="dataBlob"?type="org.hibernate.type.BlobType"?/>?
  • ????</class>?
  • ?把這里的dataBlob的type改為java.sql.Blob就可以了。

    為此,我們新建一個(gè)文件叫portal-hbm-new.xml,讓其復(fù)制portal-hbm.xml的所有內(nèi)容,除了dataBlob的type改為java.sql.Blob。

    然后我們在portal-ext.properties中添加如下行,讓hibernate映射文件指向我們新建的這個(gè)文件:

  • #added?by?charles?to?fix?the?dbStore?problem?,use?the?new?portal?hibernate?mapping?file?
  • ??hibernate.configs=\?
  • ????????META-INF/mail-hbm.xml,\?
  • ????????META-INF/portal-hbm-new.xml,\?
  • ????????META-INF/ext-hbm.xml?
  • ?這樣,我們就上傳成功了:

    我們檢查數(shù)據(jù)庫,在DLCONTENT表中果然找到了blob形式存在的圖片:

    ?

    事情2:

    第18行-19行,它最終會(huì)調(diào)用DLAppHelperLocalServiceImpladdFileEntry方法,具體不展開了,結(jié)論就是,它會(huì)在AssetEntry數(shù)據(jù)庫表中添加一條記錄:

    ?

    到此,我們?nèi)糠治鐾炅恕?/p>

    ?

    轉(zhuǎn)載于:https://blog.51cto.com/supercharles888/921761

    總結(jié)

    以上是生活随笔為你收集整理的Liferay 控制面板在指定文件夹添加Basic Document流程分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。