001package com.identityworksllc.iiq.common.threads;
002
003import com.identityworksllc.iiq.common.Ref;
004import org.apache.commons.logging.Log;
005import sailpoint.api.SailPointContext;
006import sailpoint.api.Terminator;
007import sailpoint.object.Reference;
008import sailpoint.object.SailPointObject;
009import sailpoint.tools.Util;
010
011import java.io.Serializable;
012import java.util.ArrayList;
013import java.util.Collections;
014import java.util.List;
015
016/**
017 * A serializable worker to delete a single SailPoint object or a list of objects.
018 */
019public class TerminatorWorker extends SailPointWorker implements Serializable {
020    /**
021     * Returns a TerminatorWorker for the given SailPointObject
022     * @param object The object
023     * @return The worker
024     */
025    public static TerminatorWorker forObject(SailPointObject object) {
026        List<Reference> refs = new ArrayList<>();
027        refs.add(Ref.of(object));
028        return new TerminatorWorker(refs);
029    }
030
031    /**
032     * Returns a TerminatorWorker for the given list of SailPointObjects
033     * @param objects The SailPointObjects
034     * @return the worker
035     */
036    public static TerminatorWorker forObjects(List<? extends SailPointObject> objects) {
037        List<Reference> refs = new ArrayList<>();
038        for(SailPointObject spo : Util.safeIterable(objects)) {
039            refs.add(Ref.of(spo));
040        }
041        return new TerminatorWorker(refs);
042    }
043
044    /**
045     * Make references from a class name and list of IDs
046     * @param className The class name
047     * @param ids The IDs
048     * @return A list of references
049     */
050    private static List<Reference> makeRefs(Class<SailPointObject> className, List<String> ids) {
051        List<Reference> refs = new ArrayList<>();
052        for(String id : Util.safeIterable(ids)) {
053            refs.add(Ref.of(className, id));
054        }
055        return refs;
056    }
057
058    /**
059     * The list of objects to terminate, stored as references
060     */
061    private final List<Reference> objects;
062
063    /**
064     * Required by Externalizable; don't use this please
065     */
066    public TerminatorWorker() {
067        this.objects = new ArrayList<>();
068    }
069
070    /**
071     * Creates a worker to terminate the given SailPointObject by ID
072     * @param className The class name of the object to terminate
073     * @param id The ID of the object to terminate
074     */
075    public TerminatorWorker(Class<SailPointObject> className, String id) {
076        this(className, Collections.singletonList(id));
077    }
078
079    /**
080     * Creates a worker to terminate a list of SailPointObjects by ID
081     * @param className The class name of the objects to terminate
082     * @param ids The list of IDs of the objects to terminate
083     */
084    public TerminatorWorker(Class<SailPointObject> className, List<String> ids) {
085        this(makeRefs(className, ids));
086    }
087
088    /**
089     * A new worker that will terminate a single object
090     * @param singleObject The single object reference to terminate
091     */
092    public TerminatorWorker(Reference singleObject) {
093        this(Collections.singletonList(singleObject));
094    }
095
096    /**
097     * A new worker that will terminate a list of objects
098     * @param objects The list of objects
099     */
100    public TerminatorWorker(List<Reference> objects) {
101        this.objects = new ArrayList<>(objects);
102    }
103
104    /**
105     * Invokes the Terminator on each object in the list of references.
106     *
107     * @param context The private context to use for this thread worker
108     * @param logger The log attached to this Worker
109     * @return Null; can be ignored
110     * @throws Exception if any failures occur
111     */
112    @Override
113    public Object execute(SailPointContext context, Log logger) throws Exception {
114        Terminator terminator = new Terminator(context);
115        terminator.setNoLocking(true);
116        for(Reference ref : this.objects) {
117            SailPointObject spo = ref.resolve(context);
118            if (spo != null) {
119                terminator.deleteObject(spo);
120            }
121        }
122        return null;
123    }
124}