com.amazonaws.mturk.cmd.ApproveWork.java Source code

Java tutorial

Introduction

Here is the source code for com.amazonaws.mturk.cmd.ApproveWork.java

Source

/*
 * Copyright 2012 Amazon Technologies, Inc.
 * 
 * Licensed under the Amazon Software License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 * 
 * http://aws.amazon.com/asl
 * 
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and
 * limitations under the License.
 */

package com.amazonaws.mturk.cmd;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.cli.CommandLine;

import com.amazonaws.mturk.addon.BatchItemCallback;
import com.amazonaws.mturk.requester.Assignment;
import com.amazonaws.mturk.service.axis.WorkQueue;

public class ApproveWork extends AbstractCmd implements BatchItemCallback {

    private final static String DELIM_CHAR = ",";
    private final static String ASSIGNMENT_TO_APPROVE_COLUMN = "assignmentIdToApprove";
    private final static String ASSIGNMENT_TO_APPROVE_COMMENT_COLUMN = "assignmentIdToApproveComment";
    private final static String HIT_TO_APPROVE_COLUMN = "hitid";

    private final String ARG_ASSIGNMENT = "assignment";
    private final String ARG_APPROVEFILE = "approvefile";
    private final String ARG_SUCCESSFILE = "successfile";
    private final String ARG_FORCE = "force";

    private int successCount = 0;
    private int failedCount = 0;
    private Map<String, String> resultMap = null;
    private final static String RESULT_TEMPLATE_COMMENT = " with comment '%s'";
    private final static String RESULT_TEMPLATE_HIT = " for HIT %s";
    private String resultTemplate = RESULT_TEMPLATE_COMMENT;

    public ApproveWork() {
    }

    public static void main(String[] args) {
        ApproveWork jtf = new ApproveWork();
        jtf.run(args);
    }

    protected void initOptions() {
        opt.addOption(ARG_ASSIGNMENT, true,
                "The ID of the assignment to approve (separate multiple assignment IDs with a comma)");
        opt.addOption(ARG_APPROVEFILE, true,
                "The name of the file that contains the assignment IDs to be approved (the column must be titled '"
                        + ASSIGNMENT_TO_APPROVE_COLUMN + "' and the comment column must be titled '"
                        + ASSIGNMENT_TO_APPROVE_COMMENT_COLUMN + "')");
        opt.addOption(ARG_FORCE, false, "(optional) Do not prompt for confirmation (DANGEROUS)");
        opt.addOption(ARG_SUCCESSFILE, true,
                "A path to the success file returned by the call to LoadHITs. For each HIT in the file,"
                        + "the operation attempts to approve all assignments.");
    }

    protected void printHelp() {
        formatter.printHelp(ApproveWork.class.getName() + " -" + ARG_ASSIGNMENT + " | " + " -" + ARG_APPROVEFILE
                + " [path to approval file]}", opt);
    }

    protected void runCommand(CommandLine cmdLine) throws Exception {
        if (!cmdLine.hasOption(ARG_ASSIGNMENT) && !cmdLine.hasOption(ARG_APPROVEFILE)
                && !cmdLine.hasOption(ARG_SUCCESSFILE)) {

            log.error("Missing: you must supply one of -" + ARG_ASSIGNMENT + " or -" + ARG_APPROVEFILE + " or -"
                    + ARG_SUCCESSFILE);
            System.exit(-1);

        }

        log.info("--- Starting approval ---");

        setForce(cmdLine.hasOption(ARG_FORCE));
        if (cmdLine.hasOption(ARG_ASSIGNMENT)) {
            approveAssignments(cmdLine.getOptionValue(ARG_ASSIGNMENT));
        } else if (cmdLine.hasOption(ARG_APPROVEFILE)) {
            approveAssignmentsInFile(cmdLine.getOptionValue(ARG_APPROVEFILE));
        } else if (cmdLine.hasOption(ARG_SUCCESSFILE)) {
            approveHitsInFile(cmdLine.getOptionValue(ARG_SUCCESSFILE));
        }

        // print summary
        log.info("--- Finished approval ---");
        log.info("  " + successCount + " assignments approved.");
        log.info("  " + failedCount + " assignments failed to be approved.");
        if (failedCount > 0) {
            System.exit(-1);
        }
    }

    public void approveAssignmentsInFile(String fileName) throws IOException {
        if (fileName == null) {
            throw new IllegalArgumentException("fileName must not be null");
        }

        String[] assignments = super.getFieldValuesFromFile(fileName, ASSIGNMENT_TO_APPROVE_COLUMN);

        if (assignments != null) {
            String[] comments = super.getFieldValuesFromFile(fileName, ASSIGNMENT_TO_APPROVE_COMMENT_COLUMN);

            if (comments != null) {
                if (assignments.length != comments.length) {
                    log.error("Cannot approve assignments: Row mismatch for assignment IDs and comments");
                    return;
                }

                // filter emtpy IDs (since Feature 1826272 getResults now outputs HITs without assignments)
                List<String> effectiveAssignments = new ArrayList<String>();
                List<String> effectiveComments = new ArrayList<String>();
                for (int i = 0; assignments != null && i < assignments.length; i++) {
                    if (assignments[i] != null && assignments[i].length() > 0) {
                        effectiveAssignments.add(assignments[i]);
                        effectiveComments.add(comments[i]);
                    }
                }

                assignments = new String[effectiveAssignments.size()];
                effectiveAssignments.toArray(assignments);
                comments = new String[effectiveAssignments.size()];
                effectiveComments.toArray(comments);
            }

            approveAssignments(assignments, comments);
        }
    }

    public void approveAssignments(String assignmentIds) {
        if (assignmentIds == null) {
            return;
        }

        String[] assignments = assignmentIds.split(DELIM_CHAR);
        approveAssignments(assignments);
    }

    private void approveAssignments(String[] assignments) {
        approveAssignments(assignments, null);
    }

    private void approveAssignments(String[] assignments, String[] comments) {

        // If we're not given anything, just no-op
        if (assignments == null) {
            return;
        }

        checkIsUserCertain("You are about to approve " + assignments.length + " assignment(s).");
        String defaultComment = null;

        if (comments == null) {
            defaultComment = getComment();
        }

        // setup result map for callback handler
        resultMap = new HashMap<String, String>();
        for (int i = 0; i < assignments.length; i++) {
            resultMap.put(assignments[i], (comments != null && comments[i] != null) ? comments[i] : defaultComment);
        }

        service.approveAssignments(assignments, comments, defaultComment, this);
    }

    public void approveHitsInFile(String fileName) throws IOException {
        if (fileName == null) {
            throw new IllegalArgumentException("fileName must not be null");
        }

        String[] hits = super.getFieldValuesFromFile(fileName, HIT_TO_APPROVE_COLUMN);
        resultTemplate = RESULT_TEMPLATE_HIT;

        resultMap = new HashMap<String, String>();
        List<String> assignmentIds = new ArrayList<String>();
        for (int i = 0; i < hits.length; i++) {
            try {
                Assignment[] assignments = service.getAllSubmittedAssignmentsForHIT(hits[i]);
                if (assignments != null && assignments.length > 0) {
                    for (Assignment a : assignments) {
                        assignmentIds.add(a.getAssignmentId());
                        resultMap.put(a.getAssignmentId(), a.getHITId());
                        submitAssignmentsFromHitIfNecessary(assignmentIds, WorkQueue.getNumberOfThreads()); // batch up assignments 
                    }
                }
            } catch (Exception ex) {
                log.error("ERROR submitting assignments for HIT " + hits[i] + ": " + ex.getLocalizedMessage(), ex);
            }
        }
        submitAssignmentsFromHitIfNecessary(assignmentIds, 0); // submit remaining assignments
    }

    private void submitAssignmentsFromHitIfNecessary(List<String> assignmentList, int threshold) {
        if (assignmentList.size() < threshold) {
            return;
        }

        String[] assignmentsToApprove = new String[assignmentList.size()];
        assignmentList.toArray(assignmentsToApprove);
        service.approveAssignments(assignmentsToApprove, null, null, this);

        assignmentList.clear();
    }

    public void processItemResult(Object itemId, boolean succeeded, Object result, Exception itemException) {

        String resultVal = resultMap.get(itemId);
        if (succeeded) {
            successCount++;
            log.info("[" + itemId + "] Assignment successfully approved"
                    + (resultVal != null && resultVal.length() > 0 ? String.format(resultTemplate, resultVal)
                            : ""));
        } else {
            failedCount++;
            log.error("Error approving assignment " + itemId
                    + (resultVal != null && resultVal.length() > 0 ? String.format(resultTemplate, resultVal) : "")
                    + ": " + itemException.getLocalizedMessage(), itemException);
        }
    }
}