Iam adding a file to folder by this way
if(fileExisits(folderId, title))
{
fileEntry=DLFileEntryLocalServiceUtil.getFileEntry(repositoryId, folderId, title);
serviceContext.setWorkflowAction(0);
DLFileEntryLocalServiceUtil.updateFileEntry(userId, fileEntry.getFileEntryId(), sourceFileName, mimeType, title, description, changeLog, true, fileEntry.getFileEntryTypeId(), null, null, is, size, serviceContext);
}
else
{
serviceContext.setWorkflowAction(0);
DLFileEntryLocalServiceUtil.addFileEntry(userId, repositoryId, repositoryId, folderId, sourceFileName, mimeType, title, description, changeLog, 0, null, null, is, size, serviceContext);
}
But even though it is updating or creating a dlfile it is being saved as draft.
Can anyone please help me how to change the status of dlfile programaticaly.
Maybe you should try serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH)
I found the solution i was adding user and group to servicecontext now instead iam using new ServiceContext() . By doing so iam able to create as dlfile with approvied status
Related
Creating a Web Content is easy via the UI.
But how to do add a new Web Content programmatically, in Java?
I must migrate data from a legacy system to Liferay 7, so I am writing a Java OSGI bundle to do so. No user interface.
Nicolas.
I had a similar problem to solve in Liferay 6.2, but I believe you can solve yours using the same approach.
We built a "integration interface" (a simple Java Batch project to trigger the whole thing) that comunicates with the legacy system and with a Liferay REST Service (created using Liferay Service Builder).
Liferay provides you a Service API where you can handle some of its resources. To create a Journal Article (Web Content) you must invoke the Class JournalArticleLocalServiceUtil
Here is a sample code to create a Journal Article:
public static JournalArticle addJournalArticle(
long userId, long groupId, String title, String contentEn)
throws Exception {
ServiceContext serviceContext = new ServiceContext();
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
serviceContext.setScopeGroupId(groupId);
serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);
Map<Locale, String> titleMap = new HashMap<Locale, String>();
Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
titleMap.put(Locale.US, title);
descriptionMap.put(Locale.US, title);
try {
JournalArticleLocalServiceUtil.deleteArticle(groupId, title, serviceContext);
} catch (Exception ex) {
System.out.println("Ignoring " + ex.getMessage());
}
String xmlContent = "<?xml version='1.0' encoding='UTF-8'?>" +
"<root default-locale=\"en_US\" available-locales=\"en_US\">" +
"<static-content language-id=\"en_US\">" +
"<![CDATA[" + contentEn + "]]>" +
"</static-content>" +
"</root>";
JournalArticle article = JournalArticleLocalServiceUtil.addArticle(
userId, groupId, 0,
0, 0, title, true,
JournalArticleConstants.VERSION_DEFAULT, titleMap,
descriptionMap, xmlContent,
"general", null, null, null,
1, 1, 2014, 0, 0,
0, 0, 0, 0, 0, true,
0, 0, 0, 0, 0, true,
true, false, null, null,
null, null, serviceContext);
return article;
}
But you must to improve it to put the correct user permissions, categories, tags and etc.
In such cases it helps to look at the source code.
Also consider using an Upgrade Process. While your case is not really an update it sounds like a one time operation which you would ideally perform on startup.
I'm currently facing to an issue using the Elevated Mode used in a Feature.
I have created a custome SharePoint security role (contribute role without the Delete right).
The goal of my SharePoint feature is the following:
When uploading a file to a SP Site, the name of the file needs to be renamed using the meta-data's selected. When uploading a file, a second form is asking the user to defined 3 or 4 meta-data's.
To rename the file, i have developed the following code:
Public override void ItemAdded(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
CallFunctionToUpdate();
});
}
Public override void ItemUpdated(SPItemEventProperties properties)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
CallFunctionToUpdate();
});
}
Public void CallFunctionToUpdate()
{
try
{
this.EventFiringEnabled = false;
using (SPWeb newWeb = newSite.OpenWeb(_properties.RelativeWebUrl))
{
SPListItem item = newWeb.Lists[_properties.ListId].GetItemById(_properties.ListItem.ID);
newFileName = FilenameManagementHelper.GenerateFilename(properties.ListItem);
currentName = properties.ListItem["Name"].ToString();
var extension = Path.GetExtension(currentName);
if (item["Title"] == null || item["Title"].ToString() != newFileName)
{
item["Title"] = newFileName;
item["Editor"] = new SPFieldUserValue(properties.OpenWeb(), properties.OpenWeb().CurrentUser.ID, properties.OpenWeb().CurrentUser.LoginName);
item.SystemUpdate();
}
if (currentName.Substring(0, currentName.Length - extension.Length) != newFileName)
{
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
folder.Files.Add(destUrl, bin, fileToMove.Properties, true);
fileToMove.Delete(); newWeb.Lists[list.RootFolder.Url].Update();
}
}
}
catch (Exception ex)
{
DocumentDiagnosticService.LogError(CategoryID.Error, string.Format("Error {0} for the file name - {1}", ex.Message, currentName));
}
finally
{
this.EventFiringEnabled = true;
}
}
Before renaming the file name, I'm updating the field (meta-data's) title and Editor. The second step will move the file (with the meta-data's and the history associated to the uploaded file)
I'm using the Elevated Mode because the user with a restricted Security role cannot delete. In the code developed I'm moving the file renamed and deleting the old file uploaded.
I found that approach because I need to keep the versioning. Updating directly the name of the file (like for the title) is not allowed and that's losing the history. Ex: A file will be uploaded, the name of the file will be updated using the Meta-data's. For the first version, there is no issue. Uploading a second file with the same meta-data's as there is already an existing file with the same name, that will generate an error. Using the Files.Add, that will oerride the current file and will keep the history.
My issue in this case: When the user is uploading the file, the fields Title and Editor are correctly replaced. Than is moving the file, renaming the field Name and deleting the old version. At this moment, the Modify by field is coming the SharePoint Sys Admin all the time.
How can i keep the Modifiy by with the name of the person who is uploading the file ?
EDIT:
Using the following code:
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
folder.Files.Add(destUrl, bin, fileToMove.Properties, true);
fileToMove.Delete();
Allow me to move the file with the meta-data's selected during the upload. I still have the versioning if a current version is already uploaded BUT the Modified By is SysAdmin.
Using the following code:
SPList list = newWeb.Lists[_properties.List.Title];
string destUrl = list.RootFolder.Url + "/" + newFileName + extension;
SPFile fileToMove = list.Items[_properties.ListItemUniqueId].File;
SPFolder folder = newWeb.GetFolder(list.RootFolder.Url);
byte[] bin = fileToMove.OpenBinary();
SPUser author = fileToMove.Author;
folder.Files.Add(destUrl, bin, author, author, DateTime.Now, DateTime.Now);
fileToMove.Delete();
Allow me to move the file and keep the history if i already have a version. I can now get the Modified By field filled by the real user who is uploading and not the SysAdmin BUT I'm losing the meta-data's selected during the upload.
Thank you for your support,
Fix.
Use item.Update() instead of SystemUpdate(). It should retain the identity of logged in user.
Thank you for your support.
I have solved my issue by using the following code:
folder.Files.Add(destUrl, bin, fileToMove.Properties, author, author, DateTime.Now, DateTime.Now, true);
Now, I have the Modified By value filled with the user who is uploading, the meta-data's are still there and the versioning too.
My custom asset is not visible in Asset Publisher. I created portlets and service layer according to this guide. so I have Location model. After create or update location I update entry:
public void addLocation(ActionRequest request, ActionResponse response)
throws Exception {
Location location = _updateLocation(request);
User user = PortalUtil.getUser(request);
AssetEntryLocalServiceUtil.updateEntry(user.getUserId(),
PortalUtil.getScopeGroupId(request), Location.class.getName(),
location.getLocationId(), new long[0], new String[] { "mycat1",
"mucat2" });
sendRedirect(request, response);
}
AssetEntry is stored in database:
SELECT entryid, groupid, companyid, userid, username, createdate, modifieddate,
classnameid, classpk, classuuid, classtypeid, visible, startdate,
enddate, publishdate, expirationdate, mimetype, title, description,
summary, url, layoutuuid, height, width, priority, viewcount
FROM assetentry order by createdate desc limit 1;
Result:
left side of result
right side of result
Why Asset Publisher not show my asset if asset exists in database?
Maybe I should specify some layout because Asset Publisher don't know how to show my asset.
To utilize Asset Framework properly, you need to do few more things. First of all Asset Publisher needs to know how to access your objects metadata - you have to provide custom AssetRendererFactory / AssetRenderer classes and a JSP file which will render your entity.
Read more in https://www.liferay.com/documentation/liferay-portal/6.2/development/-/ai/asset-framework-liferay-portal-6-2-dev-guide-06-en under the section Publishing Assets with Asset Publisher.
Requirement: Adding Parent folders, Child folders and Their files to Document and Library from Particular location.
Case-1: If Folder is already exists then get that id and add file
( Here I am using
addFileEntry(repositoryId, folderId,sourceFileName, mimeType, title, description, changeLog, is, size, serviceContext) of DLAppServiceUtil class ).
Case-2: If Folder is not exits add folder then add file
(Here I am using for adding folder
addFolder() method of DLAppServiceUtil class)
My case its gives slow performance. That is the problem.
Which version of Liferay are you using?
The current trend is the following in 6.1+ (well, when it is correctly implemented, but you can build more or less on this with the new DLApp implementation):
Locate the parent folder id. Use the default from the DLFolderConstancts if you don't have any.
Assume the folder exists and try to get it.
It will throw you a NoSuch***Exception if not found. If this is the case, create the folder by hand
You could do something like this:
private Folder getOrCreateFolder(final ServiceContext serviceContext,
final long userId, final Group group, String folderName)
throws PortalException, SystemException {
final long parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
final long repositoryId = group.getGroupId();
try {
final Folder prev = DLAppLocalServiceUtil.getFolder(
repositoryId, parentFolderId, folderName);
return prev;
} catch (final NoSuchFolderException e) {
final Folder newFolder = DLAppLocalServiceUtil.addFolder(userId,
repositoryId, parentFolderId, folderName,
"My cool new folder", serviceContext);
return newFolder;
}
}
The docs and stuff are absolutely leaky about why you call the addFolder() that way, take a look on the portal source. It's not that trivial but isn't that hard to get used to either.
I need to change document types (FileEntryType) for a large list of files in Liferay Document Library, but I have not been able to do so.
After hours of googeling, testing and familiarizing myself with Liferay Github repo, I decided to come here and ask for help.
This is what I have used:
ServiceContext serviceContext = new ServiceContext();
List<DLFileEntry> filesToBeUpdated = DLFileEntryServiceUtil.getFileEntries(
groupId, 0, fileEntryTypeId,
0, 10000, OrderByComparator);
for (DLFileEntry file : filesToBeUpdated) {
System.out.println("Changing file: "+ file.getName());
serviceContext.setAttribute("fileEntryTypeId", fileEntryTypeId);
DLAppServiceUtil.updateFileEntry(file.getFileEntryId(), file.getName(),
file.getMimeType(), null, file.getDescription(),
null, false, null, file.getSize(), serviceContext);
}
The files I used for testing are found correctly. The problem is with updating in the for loop: It throws always PortletException. How can I change the FileEntryType correctly?
You can also accomplish this with DLAppServiceUtil by setting the field in the ServiceContext that you pass in as the last parameter:
sc.setAttribute("fileEntryTypeId", liferayDocumentType);
Why do you use DLAppServiceUtil.updateFileEntry(...)? DLFileEntryServiceUtil has updateFileEntry method that accepts long fileEntryTypeId as a parameter.