掲示板

How get the fileEntryId for a new document

thumbnail
6年前 に Marco Azzalini によって更新されました。

How get the fileEntryId for a new document

Regular Member 投稿: 146 参加年月日: 14/11/18 最新の投稿
Hi, I have modified the edit_file_entry.jsp page adding a couple of textbox fields and when the user press the Save button I need to read those fields. Following Liferay tutorial I overrided the struts action and in my processAction() I can read my custom fields value (they are all in the ServiceContext's attributes) and this is great! Unfortunately I CAN'T read the fileEntryId that it has been just created from the original struts action, because the variable fileEntry is local in his processAction method (!!)

FileEntry fileEntry = null;
.....
... if (cmd.equals(Constants.ADD) ||
					 cmd.equals(Constants.ADD_DYNAMIC) ||
					 cmd.equals(Constants.UPDATE) ||
					 cmd.equals(Constants.UPDATE_AND_CHECKIN)) {

				fileEntry = updateFileEntry(portletConfig, actionRequest, actionResponse);


So I am stuck! If I move down in the calls chain (ServiceWrapper, Listener...) is easy to get the fileEntryId but I lose all my textbox values :-(
Any hints?

Marco
thumbnail
6年前 に Andrew Jardine によって更新されました。

RE: How get the fileEntryId for a new document

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
Hi Marco,

Have you tried passing it from the end of the processAction using (for example)

actionResponse.setRenderParameter("fileEntryId", fileEntry.getFileEntryId())


.. that should then make it available in the render phase for you to use. Would that work?
thumbnail
6年前 に Marco Azzalini によって更新されました。

RE: How get the fileEntryId for a new document

Regular Member 投稿: 146 参加年月日: 14/11/18 最新の投稿
Andrew Jardine:
Hi Marco,

Have you tried passing it from the end of the processAction using (for example)

actionResponse.setRenderParameter("fileEntryId", fileEntry.getFileEntryId())


.. that should then make it available in the render phase for you to use. Would that work?


Hi Andrew, thank s for your suggestion. I am not sure but when you say 'at the end of the processAction' do you mean in the original Struts action class or in my class? Could you give more details?

thanks
Marco
thumbnail
6年前 に Andrew Jardine によって更新されました。

RE: How get the fileEntryId for a new document

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
Hi Marco,

Not the original one, I meant at the end of your custom action. The update method should return to you the "updated" file entry so you can then pick is apart and add whatever render parameters you want.

If that doesn't make sense, maybe if you can share with us your entire struts action override class I can point to the right line numbers for you?
thumbnail
6年前 に Marco Azzalini によって更新されました。

RE: How get the fileEntryId for a new document

Regular Member 投稿: 146 参加年月日: 14/11/18 最新の投稿
Andrew Jardine:
Hi Marco,

Not the original one, I meant at the end of your custom action. The update method should return to you the "updated" file entry so you can then pick is apart and add whatever render parameters you want.

If that doesn't make sense, maybe if you can share with us your entire struts action override class I can point to the right line numbers for you?

Hi Andrew, sorry but I can't catch your idea (maybe my Alzheimer's disease is getting worse :-D ). I mean that I don't have any update method in my struts action class because my class doesn't extends the original one so I can't ovveride the original update method.
I followed this liferay tutorial: 'Overriding and Adding Struts Actions ' and this is my code
public class MyEditFileEntryAction extends BaseStrutsPortletAction {
	
	public void processAction(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { 
		String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
		
		try {
			if (cmd.equals(Constants.ADD) ||
					 cmd.equals(Constants.UPDATE) ||
					 cmd.equals(Constants.UPDATE_AND_CHECKIN)) {

				UploadPortletRequest uploadPortletRequest =
						PortalUtil.getUploadPortletRequest(actionRequest);
				ServiceContext serviceContext = ServiceContextFactory.getInstance(
						DLFileEntry.class.getName(), uploadPortletRequest);
				
            // here I can read all my custom field's values  in the jsp page (through the serviceContext) and

				originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest,actionResponse);
				
               // here I would like to read also the fileEntryId just created/modified
               //.....
			
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	
	public String render(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
			
                        //System.out.println("My Custom Render Method is Called"); 
			return originalStrutsPortletAction.render(null, portletConfig, renderRequest, renderResponse); 
	}
}


After the process Action of the original action, I would like to have a wayto get the fileEntryId....
Thanks again for all your support
Marco
thumbnail
6年前 に Andrew Jardine によって更新されました。

RE: How get the fileEntryId for a new document

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
Oh I see now what you meant. Apologies, I misunderstood -- I thought you were overriding the action completely. I ran into this issue recently actually and I found a solution, though I wasn't sure it was the best option at the time. In my case I had to distinguish between the ADD and the UPDATE methods. The reason being that in the case of an UPDATE scenario there is actually a fileEntryId in the request, otherwise I used the fields that we passed when the item was added to retrieve the file object that was just added. This works for our case, but we're no in an environment that is under a lot of load or one that contains files with the same names, etc. Here is a stub of the process action that we used.

public void processAction(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception
{
     // perform original action first
     originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest, actionResponse);

     // get the command
     String cmd = ParamUtil.getString(actionRequest, Constants.CMD);

     FileEntry fileEntry = null;

     // if the command is add or update grab the publish date and set the expando value
     if ( cmd.equals(Constants.UPDATE) )
     {
         long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId", 0);

         if ( fileEntryId > 0 )
         {
            // do something here
         }
     }
     else if ( cmd.equals(Constants.ADD) )
     {
         String title = ParamUtil.getString(actionRequest, "title", null);
         long folderId = ParamUtil.getLong(actionRequest, "folderId", -1);
         long groupId = PortalUtil.getScopeGroupId(actionRequest);

         fileEntry = DLAppLocalServiceUtil.getFileEntry(groupId, folderId, title);

         if ( fileEntry != null )
         {
             // do something here
         }
     }


     if ( Validator.isNotNull(fileEntry) )
     {
         Indexer indexer = IndexerRegistryUtil.getIndexer(DLFileEntry.class);

         if ( _log.isDebugEnabled())
             _log.debug(LogUtil.format("indexer retrieved: " + indexer.getClass().getName()));

         indexer.reindex(fileEntry);
     }
 }



... again, I don't want to advocate this as the best solution because I can think of a few scenarios where this might not stand up, but for our solution, given our constraints, it was an acceptable solution.

Ideally you would be able to access the updateFileEntry on the originalStrutsAction, but it's protected so no dice. I suppose another alternative is to use an EXT plugin and then create you custom action such that it EXTENDS the EditFileEntryAction ... then you could access the protected method and use something cleaner like this --

public class MyEditFileEntryAction extends BaseStrutsPortletAction {
    
    public void processAction(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { 
        String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
        
        try {
            if (cmd.equals(Constants.ADD) ||
                     cmd.equals(Constants.UPDATE) ||
                     cmd.equals(Constants.UPDATE_AND_CHECKIN)) {

                  
                  
                UploadPortletRequest uploadPortletRequest =
                        PortalUtil.getUploadPortletRequest(actionRequest);
                ServiceContext serviceContext = ServiceContextFactory.getInstance(
                        DLFileEntry.class.getName(), uploadPortletRequest);


              fileEntry = updateFileEntry(portletConfig, actionRequest, actionResponse);
            }
            else {
              originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest,actionResponse);
      
            }        
          }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    
    public String render(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, RenderRequest renderRequest, RenderResponse renderResponse) throws Exception {
            
                        //System.out.println("My Custom Render Method is Called"); 
            return originalStrutsPortletAction.render(null, portletConfig, renderRequest, renderResponse); 
    }
}


.. personally though I try to avoid EXT plugins like they are the plague. If you already have one in your solution though, then you might as well get the most of out it. I am curious to know which option you go with so let me know emoticon
thumbnail
6年前 に Marco Azzalini によって更新されました。

RE: How get the fileEntryId for a new document

Regular Member 投稿: 146 参加年月日: 14/11/18 最新の投稿
Hy Andrew, thanks a lot for your reply. In the meantime my requirements has changed and now I haven't anymore the needs of doing my stuff during the FileEntry creation. This gave me the opportunity to move my business logic after the FileEntry creation and all the things have become easier ;-)
About your solution, I am agree with you, it is suitable in particular circumstances but the overall schema is good, so I will keep it in mind for the next time.
Thanks!
Marco
thumbnail
5年前 に Marco Azzalini によって更新されました。

RE: How get the fileEntryId for a new document (回答)

Regular Member 投稿: 146 参加年月日: 14/11/18 最新の投稿

Hi, some weeks ago I think I found a general solution for this problem ;-)

Following is the solution I set up.

To get the id of a newly inserted document, before the struts action EditFileEntryAction returns it is sufficient to make a wrapper for DLFileEntryLocalService and override the method

public DLFileEntry addFileEntry(......)

For whom don't know (like me), this method is called before the EditFileEntry struts action and it returns the DLFileEntry just created ;-)

At this point the solution is to have a shared object (I used a simple hashmap wrapper to keep separated the document's id between users, in case of simultaneous inserts) between the service wrapper and EditFileEntryAction to pass the fileEntry's id (unfortunately, all my tries to use the service context object for this, has failed).

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 {

            ....

            DLFileEntry fe= super.addFileEntry(userId, groupId, repositoryId, folderId,
                    sourceFileName, mimeType, title, description, changeLog,
                    fileEntryTypeId, fieldsMap, file, is, size, serviceContext);

            MySharedMap.setLastFileEntryIdByUser(userId,fe.getFileEntryId());
            ....

after this, the EditFileEntryAction#processAction  is called and we can use the id, for example,  to redirect on the preview page of the new document itself(!)

 

public class EditFileEntryAction extends BaseStrutsPortletAction {
    
    public void processAction(StrutsPortletAction originalStrutsPortletAction, 
                              PortletConfig portletConfig,
                              ActionRequest actionRequest, ActionResponse actionResponse) throws Exception { 
        
        String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
            .....

           if (Validator.isNull(cmd)) {
                return; 
            } else if (cmd.equals(Constants.ADD)  {
                UploadPortletRequest uploadPortletRequest =PortalUtil.getUploadPortletRequest(actionRequest);
                
                ThemeDisplay themeDisplay= (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
                
                originalStrutsPortletAction.processAction(originalStrutsPortletAction, portletConfig, actionRequest,actionResponse);
               
                String fileEntryId=MySharedMap.getLastFileEntryIdByUser(themeDisplay.getUserId());
                if (! fileEntryId.equals("") ) {
                    PortletURL viewFileEntryURL = PortletURLFactoryUtil.create(actionRequest, PortletKeys.DOCUMENT_LIBRARY , themeDisplay.getPlid(), actionRequest.RENDER_PHASE);
                    
                    viewFileEntryURL.setParameter("struts_action", "/document_library/view_file_entry");
                    viewFileEntryURL.setParameter("fileEntryId", String.valueOf(fileEntryId));                
                    viewFileEntryURL.setWindowState(LiferayWindowState.NORMAL);
                    viewFileEntryURL.setPortletMode(LiferayPortletMode.VIEW);                
                    NosDocPortlet.setLastFileEntryIdByUser(themeDisplay.getUserId(),"");
    
                    actionResponse.sendRedirect(viewFileEntryURL.toString());
                }
            }

I hope this can help someone else...

 

regards,

Marco