1

Hello StackOverflow Community,

Requirement: I need advice and help on going about how to create a Liferay(LR) module that will create XLS files with information pulled from a DB, and store them to a folder location in Document Library(DL), during scheduled times throughout the week.

Solution: I solutionized to use LR's Service Builder+DL+Quartz Scheduler+Apache POI. Code below.

Roadblock: The receive() method requires a RenderRequest object so that the ThemeDisplay and ServiceContext object can be created, which will be used by the DLAppServiceUtil to create the file in DL. How do I go about creating a RenderRequest object?

@Override
public void receive(Message message) throws MessageListenerException {
    _log.debug(">> receive()");

    ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
    fileUploadByApp("folder-1", themeDisplay, renderRequest);

    _log.debug("<< receive()");
}

public void fileUploadByApp(String folderName, ThemeDisplay themeDisplay, RenderRequest renderRequest) {

    try {
        File file = new File("D:/liferay-portal-6.2-ce-ga6/temp/sample_" + getDateTimeBasedFilename() + ".txt");

        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
        writer.write("Something");
        writer.close();

        long repositoryId = themeDisplay.getScopeGroupId();
        String mimeType = MimeTypesUtil.getContentType(file);
        String title = file.getName();
        String description = "This file is added via programatically";
        String changeLog = "hi";
        Long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;

        Folder folder = DLAppServiceUtil.getFolder(themeDisplay.getScopeGroupId(), parentFolderId, folderName);
        ServiceContext serviceContext = ServiceContextFactory.getInstance(DLFileEntry.class.getName(),
                renderRequest);
        InputStream is = new FileInputStream(file);
        DLAppServiceUtil.addFileEntry(repositoryId, folder.getFolderId(), file.getName(), mimeType, title,
                description, changeLog, is, file.length(), serviceContext);

    } catch (Exception e) {
        System.out.println("Exception");
        e.printStackTrace();
    }
}

Project repo, click here

MrC0mm0n
  • 175
  • 1
  • 8

2 Answers2

0

First of all, method receive doesn't require RenderRequest object, but your method fileUploadByApp. If you look carefully in your method, all what you need from ThemeDisplay is scopeGroupId. RenderRequest object, as you mentioned, is required for creating ServiceContext, but you have at least 2 solutions for this.

  1. Get some instance from ServletContextPool (if its possible).
  2. Create object manually

In second case you can setup what you need, but I think you need setup only scopeGroupId and it will work as you want.

Example of changes:

@Override
public void receive(Message message) throws MessageListenerException {
    _log.debug(">> receive()");

    ServiceContext serviceContext = new ServiceContext();
    serviceContext.setScopeGroupId(YOUR_SCOPE_GROUP_ID); //For example YOUR_SCOPE_GROUP_ID can be received from message.
    fileUploadByApp("folder-1", serviceContext);

    _log.debug("<< receive()");
}

public void fileUploadByApp(String folderName, ServiceContext serviceContext) {

    try {
        File file = new File("D:/liferay-portal-6.2-ce-ga6/temp/sample_" + getDateTimeBasedFilename() + ".txt");

        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
        writer.write("Something");
        writer.close();

        long repositoryId = serviceContext.getScopeGroupId();
        String mimeType = MimeTypesUtil.getContentType(file);
        String title = file.getName();
        String description = "This file is added via programatically";
        String changeLog = "hi";
        Long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;

        Folder folder = DLAppServiceUtil.getFolder(serviceContext.getScopeGroupId(), parentFolderId, folderName);

        InputStream is = new FileInputStream(file);
        DLAppServiceUtil.addFileEntry(repositoryId, folder.getFolderId(), file.getName(), mimeType, title,
                description, changeLog, is, file.length(), serviceContext);

    } catch (Exception e) {
        System.out.println("Exception");
        e.printStackTrace();
    }
}
glw
  • 1,646
  • 1
  • 16
  • 20
0

Thanks glw. The code provided helped joining the dots. I got it to work with the below solution in addition to the snippet you provided.

// Repository ID of the document library, figured is out by the output from
// _log.debug("repositoryId: " + repositoryId);
// in
// fileUploadByApp(folderName, themeDisplay, renderRequest).
// I found the entry in 'ddmcontent' table of LR's default DB
private long siteARepoId = ?????;
// Found this in 'company' table of LR's default DB
private long LRCompanyId = ?????;
private String sAdminRole = "Administrator";

@Override
public void receive(Message message) throws MessageListenerException {
    _log.debug(">> receive()");

    ServiceContext serviceContext = new ServiceContext();
    serviceContext.setScopeGroupId(siteARepoId);
    fileUploadByApp(DLFolderLocation, serviceContext);

    _log.debug("<< receive()");
}

public void fileUploadByApp(String folderName, ServiceContext serviceContext) {
    _log.debug(">> fileUploadByApp(folderName, serviceContext)");

    try {
        File file = new File(LRTempLocation + "excel_" + getDateTimeBasedFilename() + ".xlsx");

        createExcel(file);

        long repositoryId = serviceContext.getScopeGroupId();
        String mimeType = MimeTypesUtil.getContentType(file);
        String title = file.getName();
        String description = "This file is added via programatically";
        String changeLog = "hi";
        Long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;

        _log.debug("repositoryId: " + repositoryId);
        _log.debug("fileName: " + file.getName());
        _log.debug("mimeType: " + mimeType);
        _log.debug("title: " + title);
        _log.debug("description: " + description);
        _log.debug("changeLog: " + changeLog);
        _log.debug("fileLength: " + file.length());
        _log.debug("serviceContext: " + serviceContext);

        Folder folder = DLAppLocalServiceUtil.getFolder(repositoryId, parentFolderId, folderName);

        _log.debug("folderId: " + folder.getFolderId());

        InputStream is = new FileInputStream(file);

        _log.debug("inputStream: " + is);

        // Initializing PermissionChecker, without the below the exception
        // occurs
        // Caused by: com.liferay.portal.security.auth.PrincipalException:
        // PermissionChecker not initialized
        // Source:
        // http://www.open.gr/blog/2014/05/permissionchecker-not-initialised-scheduler-job
        Company companyqq = CompanyLocalServiceUtil.getCompanyById(LRCompanyId);
        Role adminRole = RoleLocalServiceUtil.getRole(companyqq.getCompanyId(), sAdminRole);
        List<User> adminUsers = UserLocalServiceUtil.getRoleUsers(adminRole.getRoleId());
        PrincipalThreadLocal.setName(adminUsers.get(0).getUserId());
        PermissionChecker permissionChecker = PermissionCheckerFactoryUtil.create(adminUsers.get(0), true);
        PermissionThreadLocal.setPermissionChecker(permissionChecker);

        // Adding the file entry to the Document Library
        DLAppServiceUtil.addFileEntry(repositoryId, folder.getFolderId(), file.getName(), mimeType, title,
                description, changeLog, is, file.length(), serviceContext);

    } catch (Exception e) {
        System.out.println("Exception");
        e.printStackTrace();
    }

    _log.debug("<< fileUploadByApp(folderName, serviceContext)");
}

Project Link, click here

MrC0mm0n
  • 175
  • 1
  • 8