You are viewing limited content. For full access, please sign in.

Question

Question

Update Metadata Through Java

SDK
asked on August 22, 2014

 I am writing test code to update metadata on an LF document.  While LF has little or no Java sample code, I have translated C# code from the help file.  My snippet:

Entry entry = row.toEntry(); //where the row represents my document
FieldValueCollection fvc = entry.getFields();
fvc.set("Article", "obstructions and excavations");
entry.lock(LockType.EXCLUSIVE);
entry.setFields(fvc);
entry.save();
entry.unlock();

I confirmed I am not running a readonly session (session.isReadOnly=false) and that I have rights (full gamut of effective rights, yet when I get to the save line I throw a MultiStatusException with a long message starting with "access denied".

 

Any insights as to how to get around this?

0 0

Replies

replied on August 22, 2014

Do you have write access to the "Article" field? That is a field access right and not an entry access right.

1 0
replied on August 25, 2014

Good thought, permissions are so often the issue, but in this case I think not.

 

The programmatic effective rights to the field are: READ_VALUE, SET_VALUE, SET_VALUE_ONCE, MODIFY_DEFINITION, DELETE, READ_PERMISSIONS, CHANGE_PERMISSIONS, TAKE_OWNERSHIP and to the entry: BROWSE, READ, WRITE_CONTENT, ADD_PAGE, RENAME, REMOVE_PAGE, FREEZE, ANNOTATE, SEE_THROUGH_REDACTIONS, SEE_ANNOTATIONS, SET_REVIEW_DATE, WRITE_METADATA, CREATE_FOLDER, CREATE_DOCUMENT, SET_EVENT_DATE, CLOSE, DELETE, READ_PERMISSIONS, CHANGE_PERMISSIONS, TAKE_OWNERSHIP.

 

When I log into the repository through the LF Client with the same ID I can modify all the fields on the entry in question.  Did I miss something?

 

I appreciate your response.

0 0
replied on August 25, 2014

While I haven't dug through all the details, the essence of my mistake was getting the full FieldValueCollection from the entity, updating one of the fields within it and setting that back onto the entity.  A technique which seems to work is to create a new FieldValueCollection and add the one field to update and it's value to that collection and set that onto the entity e.g.

Entry entry = row.toEntry(); //where the row represents my document
// don't get the existing FieldValueCollection
//FieldValueCollection fvc = entry.getFields();
// create a new one
FieldValueCollection fvc = new FieldValueCollection();
// get the field from the template
Template template = Template.getByName(entry.getTemplate(), session);
Field articleField = template.getFields().get("Article");
// don't set the value as before
//fvc.set("Article", "obstructions and excavations");
// add it
newFvc.add(articleField, "obstructions and excavations");
entry.lock(LockType.EXCLUSIVE);
entry.setFields(fvc);
entry.save();
entry.unlock();

It works.

 

To deepen my understanding I may try playing with the FieldValueCollection that I derive from the entity to see if I can remove all the fields except the one I want to update, but that's a task for another day.

 

One other issue that I thought I bumped into.  My impression is that every time I issue

row.toEntry()

I get a brand new entry object, i.e. the values that may have been set with previous setFields methods are not associated with the entry.  I made the mistake of doing things like:

row.toEntry().setFields(fvc);

and did not get what I expected.  Once I created an Entity object and referred to it that problem went away.  The Javadocs seem to jive with that notion.  toEntry() on EntryListingRow says "Returns an Entry derived class instance which represents the entry whose information is contained in this row."

0 0
replied on June 23, 2017

Good morning/afternoon,

I am stuck on this scenario.  I am developing a C# app at this time.  I can insert a document and update its metadata:

            try
            {
                FolderInfo parentFolder = Folder.GetFolderInfo("\\folder", session);
                DocumentInfo document = new DocumentInfo(session);
                document.Create(parentFolder, "myNewDocument - " + DateTime.UtcNow.ToString(), EntryNameOption.None);
               document.SetTemplate("General");
 
               FieldValueCollection fv = new FieldValueCollection();
                fv.Add("Document", "This is the document name");
                fv.Add("Type", "This is the document type");
                fv.Add("Category", "This is the document category");

                document.SetFieldValues(fv);
                document.Save();
            }

When I attempt to update a single value of this existing document - lets say the "Document" value, I can do so but I also wipe out the values for "Type" and "Category".  I tried to follow the suggested approach above, but I get the same results if I update entryInfo or docInfo.  I don't seem to have access to calls which may help me along.  I am using version 9.0 of the SDK.

Template template = Template.getByName(entry.getTemplate(), session);

Field articleField = template.getFields().get("Article");

                EntryInfo entryInfo = Entry.GetEntryInfo(entryId, session);
                if (entryInfo.EntryType == EntryType.Shortcut)
                    entryInfo = Entry.GetEntryInfo(((ShortcutInfo)entryInfo).TargetId, session);

                // Now entry should be the DocumentInfo
                if (entryInfo.EntryType == EntryType.Document)
                {
                    DocumentInfo docInfo = (DocumentInfo)entryInfo;

                    FieldValueCollection fv = new FieldValueCollection();
                    fv.Add("Document", "Document");

                    //docInfo.SetFieldValues(fv);
                    entryInfo.SetFieldValues(fv);
                    entryInfo.Save();

                    //docInfo.Save();
                }

 

0 0
replied on June 23, 2017 Show version history

Hello again,

I think I have resolved my issue:  Essentially I am going to grab the existing FieldValueCollection from the document and update the attribute I care about as opposed to creating a new FieldValueCollection each time.  I am going to post this here in case it might benefit other readers.

 

                EntryInfo entryInfo = Entry.GetEntryInfo(entryId, session);
                if (entryInfo.EntryType == EntryType.Shortcut)
                    entryInfo = Entry.GetEntryInfo(((ShortcutInfo)entryInfo).TargetId, session);

                // Now entry should be the DocumentInfo
                if (entryInfo.EntryType == EntryType.Document)
                {
                    DocumentInfo docInfo = (DocumentInfo)entryInfo;

                    FieldValueCollection fv = docInfo.GetFieldValues();
                    fv.Remove("Document");
                    fv.Add("Document", "Document");
                    docInfo.SetFieldValues(fv);
                    docInfo.Save();
                }

 

0 0
replied on March 27, 2018 Show version history

Having run into the same problem, the issue is really with the keyword New. If you create a New FieldValueCollection, when the update is called (SetFieldValues or SetTemplate), a New FieldValueCollection will entirely replace the existing one, wiping out all of the prior fields.

What it comes down to is that if you are creating a new document the New keyword is appropriate.  If you are updating an existing document that already has fields, you should not use New. Instead retrieve the DocInfo's FieldValue collection. 

We had a module we wanted to use to either add fields to a new document, or update fields on an existing document.  We created an optional flag, created the FieldValueCollection as a generic object, and then ran this if/then:

 

// Define the FieldValueCollection
if ((bUpdateDoc == true)) {
    LF_FieldValues = LF_DocInfo.GetFieldValues();
}
else {
    LF_FieldValues = new FieldValueCollection();
}

Then you can use

    LF_DocInfo.SetTemplate(sTemplate, LF_FieldValues);

For either case.  All your existing field values will be preserved.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.