Search code examples
javafilenet-p8filenet-content-engine

FileNET P8 5.2.1 FP2 - edit permissions on document creation


We're asked to set up permissions when a document is created.

Basically the code part written is reproduced below :

public void onEvent(ObjectChangeEvent event, Id eventId) {
    if (event instanceof CreationEvent) {
        Document doc = (Document) event.get_SourceObject();
        AccessPermissionList permissions = doc.get_Permissions();
        String creatorGranteeName = getCreatorGranteeName(doc);
        Iterator<AccessPermission> iter = permissions.iterator();
        boolean found = false;
        while (iter.hasNext()) {
            AccessPermission ace = (AccessPermission) iter.next();
            if (ace.get_GranteeName().equals(creatorGranteeName)) {
                permissions.remove(ace);
                // relevant ? is "permission" duplicated ?
                doc.set_Permissions(permissions);
                break;
            }
        }
        if (!found) return ; // no need to save
        doc.save(RefreshMode.REFRESH); // --> triggers CreationEvent -> loop
        System.out.println("Saved."); // never reached
    }
}

I tried two ways : a preprocessor or a subscription.

Preprocessor doesn't work since the document doesn't seems to be fully built, especially about permissions (only administrators are set). Fetching doesn't seem to work (which is understandable, since the document isn't yet stored).

Susbcription crashes if it's synchronously processed at doc.save() line, regardless if the refresh mode is RefreshMode.REFRESH or RefreshMode.NO_REFRESH. If it's asynchrounsly done, it seems to loop, as if doc.save retriggers a CreationEvent.

So I'm looking for a help if I did something wrong, or for a third way if it exists.

EDIT : added block code which skips saving if no permissions to remove was found.


Solution

  • As said by @Manjunatha Muniyappa, I solved my problem by fetching the document from the Object store rather than getting it from the CreationEvent object. It seems to be recommended by the editor ("as a best practice, fetch the persisted source object of the event"). Also by this way the CreationEvent won't be raised (I dunno why).

    So the solution is to create an asynchronous subscription on Creation Event, associated with this handler class below :

    // Only relevant lines are kept.
    public class CustomEventAction implements EventActionHandler {
        // [...]
        public void onEvent(ObjectChangeEvent event, Id eventId) {
            if (event instanceof CreationEvent) {
                ObjectStore os = event.getObjectStore();
                Id id = event.get_SourceObjectId();
                FilterElement fe = 
                        new FilterElement(null, null, null, "permissions creator", null);
                PropertyFilter pf = new PropertyFilter();
                pf.addIncludeProperty(fe);
                Document doc = Factory.Document.fetchInstance(os, id, pf);
                
                AccessPermissionList permissions;
            
                String creatorGranteeName = getCreatorGranteeName(doc);
                permissions = doc.get_Permissions();
                Iterator<AccessPermission> iter = permissions.iterator();
                
                boolean found = false;
                while (iter.hasNext()) {
                    AccessPermission ace = (AccessPermission) iter.next();
                    if (ace.get_GranteeName().equals(creatorGranteeName)) {
                        permissions.remove(ace);
                        found = true;
                        break;
                    }
                }
                
                if (!found) {
                    return;
                }
                
                doc.save(RefreshMode.REFRESH);
            }
        }
    }