Search in sources :

Example 51 with StatusMessage

use of teammates.common.util.StatusMessage in project teammates by TEAMMATES.

the class AdminEmailComposePageAction method execute.

@Override
protected ActionResult execute() {
    gateKeeper.verifyAdminPrivileges(account);
    AdminEmailComposePageData data = new AdminEmailComposePageData(account, sessionToken);
    String idOfEmailToEdit = getRequestParamValue(Const.ParamsNames.ADMIN_EMAIL_ID);
    boolean isEmailEdit = idOfEmailToEdit != null;
    if (isEmailEdit) {
        data.emailToEdit = logic.getAdminEmailById(idOfEmailToEdit);
        statusToAdmin = data.emailToEdit == null ? "adminEmailComposePage Page Load : " + Const.StatusMessages.EMAIL_NOT_FOUND : "adminEmailComposePage Page Load : Edit Email " + "[" + SanitizationHelper.sanitizeForHtml(data.emailToEdit.getSubject()) + "]";
        if (data.emailToEdit == null) {
            isError = true;
            statusToUser.add(new StatusMessage(Const.StatusMessages.EMAIL_NOT_FOUND, StatusMessageColor.WARNING));
        }
        return createShowPageResult(Const.ViewURIs.ADMIN_EMAIL, data);
    }
    statusToAdmin = "adminEmailComposePage Page Load";
    data.init();
    return createShowPageResult(Const.ViewURIs.ADMIN_EMAIL, data);
}
Also used : AdminEmailComposePageData(teammates.ui.pagedata.AdminEmailComposePageData) StatusMessage(teammates.common.util.StatusMessage)

Example 52 with StatusMessage

use of teammates.common.util.StatusMessage in project teammates by TEAMMATES.

the class InstructorFeedbackEditSaveActionTest method testExecuteAndPostProcess.

@Override
@Test
public void testExecuteAndPostProcess() {
    InstructorAttributes instructor1ofCourse1 = typicalBundle.instructors.get("instructor1OfCourse1");
    FeedbackSessionAttributes session = typicalBundle.feedbackSessions.get("session1InCourse1");
    String expectedString = "";
    ______TS("failure: Not enough parameters");
    gaeSimulation.loginAsInstructor(instructor1ofCourse1.googleId);
    verifyAssumptionFailure();
    // TODO make sure IFESA does assertNotNull for required parameters then uncomment
    // verifyAssumptionFailure(Const.ParamsNames.COURSE_ID, instructor1ofCourse1.courseId,
    // Const.ParamsNames.FEEDBACK_SESSION_NAME, session.feedbackSessionName);
    ______TS("success: Typical case");
    String[] params = createParamsForTypicalFeedbackSession(instructor1ofCourse1.courseId, session.getFeedbackSessionName());
    InstructorFeedbackEditSaveAction a = getAction(params);
    AjaxResult ar = getAjaxResult(a);
    InstructorFeedbackEditPageData pageData = (InstructorFeedbackEditPageData) ar.data;
    StatusMessage statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, Const.StatusMessages.FEEDBACK_SESSION_EDITED, StatusMessageColor.SUCCESS);
    assertFalse(pageData.getHasError());
    expectedString = "TEAMMATESLOG|||instructorFeedbackEditSave|||instructorFeedbackEditSave|||true|||" + "Instructor|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1|||" + "instr1@course1.tmt|||Updated Feedback Session " + "<span class=\"bold\">(First feedback session)</span> for Course " + "<span class=\"bold\">[idOfTypicalCourse1]</span> created.<br>" + "<span class=\"bold\">From:</span> 2012-01-31T16:00:00Z" + "<span class=\"bold\"> to</span> 2014-12-31T16:00:00Z<br>" + "<span class=\"bold\">Session visible from:</span> 2011-12-31T16:00:00Z<br>" + "<span class=\"bold\">Results visible from:</span> 1970-06-22T00:00:00Z<br><br>" + "<span class=\"bold\">Instructions:</span> " + "<Text: instructions>|||/page/instructorFeedbackEditSave";
    AssertHelper.assertLogMessageEquals(expectedString, a.getLogMessage());
    ______TS("failure: Fixed offset time zone");
    params[25] = "UTC+08:00";
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    expectedString = "\"UTC+08:00\" is not acceptable to TEAMMATES as a/an time zone because it is not " + "available as a choice. The value must be one of the values from the time zone dropdown selector.";
    statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, expectedString, StatusMessageColor.DANGER);
    assertTrue(pageData.getHasError());
    ______TS("failure: Invalid parameters");
    params[15] = "Thu, 01 Mar, 2012";
    params[25] = "UTC";
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    expectedString = "The start time for this feedback session cannot be " + "earlier than the time when the session will be visible.";
    statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, expectedString, StatusMessageColor.DANGER);
    assertTrue(pageData.getHasError());
    ______TS("success: Time zone with DST, gap start time, overlap end time");
    params[25] = "Europe/Andorra";
    // After Sun, 25 Mar 2012, 01:59:59 AM: clocks sprang forward to Sun, 25 Mar 2012, 03:00:00 AM
    params[5] = "Sun, 25 Mar, 2012";
    params[7] = "2";
    // After Sun, 28 Oct 2012, 02:59:59 AM: clocks fell back to Sun, 28 Oct 2012, 02:00:00 AM
    params[9] = "Sun, 28 Oct, 2012";
    params[11] = "2";
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    expectedString = String.format(Const.StatusMessages.AMBIGUOUS_LOCAL_DATE_TIME_GAP, "start time", "Sun, 25 Mar 2012, 02:00 AM", "Sun, 25 Mar 2012, 03:00 AM CEST (UTC+0200)");
    verifyStatusMessage(pageData.getStatusMessagesToUser().get(0), expectedString, StatusMessageColor.WARNING);
    expectedString = String.format(Const.StatusMessages.AMBIGUOUS_LOCAL_DATE_TIME_OVERLAP, "end time", "Sun, 28 Oct 2012, 02:00 AM", "Sun, 28 Oct 2012, 02:00 AM CEST (UTC+0200)", "Sun, 28 Oct 2012, 02:00 AM CET (UTC+0100)", "Sun, 28 Oct 2012, 02:00 AM CEST (UTC+0200)");
    verifyStatusMessage(pageData.getStatusMessagesToUser().get(1), expectedString, StatusMessageColor.WARNING);
    expectedString = Const.StatusMessages.FEEDBACK_SESSION_EDITED;
    verifyStatusMessage(pageData.getStatusMessagesToUser().get(2), expectedString, StatusMessageColor.SUCCESS);
    assertFalse(pageData.getHasError());
    ______TS("success: Custom time zone, 'never' show session, 'custom' show results");
    params = createParamsForTypicalFeedbackSession(instructor1ofCourse1.courseId, session.getFeedbackSessionName());
    params[25] = "Asia/Kathmandu";
    params[13] = Const.INSTRUCTOR_FEEDBACK_SESSION_VISIBLE_TIME_NEVER;
    params[19] = Const.INSTRUCTOR_FEEDBACK_RESULTS_VISIBLE_TIME_LATER;
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, Const.StatusMessages.FEEDBACK_SESSION_EDITED, StatusMessageColor.SUCCESS);
    assertFalse(pageData.getHasError());
    expectedString = "TEAMMATESLOG|||instructorFeedbackEditSave|||instructorFeedbackEditSave|||true|||" + "Instructor|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1|||" + "instr1@course1.tmt|||Updated Feedback Session " + "<span class=\"bold\">(First feedback session)</span> for Course " + "<span class=\"bold\">[idOfTypicalCourse1]</span> created.<br>" + "<span class=\"bold\">From:</span> 2012-01-31T18:15:00Z" + "<span class=\"bold\"> to</span> 2014-12-31T18:15:00Z<br>" + "<span class=\"bold\">Session visible from:</span> 1970-11-27T00:00:00Z<br>" + "<span class=\"bold\">Results visible from:</span> 1970-01-01T00:00:00Z<br><br>" + "<span class=\"bold\">Instructions:</span> " + "<Text: instructions>|||/page/instructorFeedbackEditSave";
    AssertHelper.assertLogMessageEquals(expectedString, a.getLogMessage());
    ______TS("success: At open session visible time, custom results visible time, UTC");
    params = createParamsCombinationForFeedbackSession(instructor1ofCourse1.courseId, session.getFeedbackSessionName(), 1);
    params[25] = "UTC";
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, Const.StatusMessages.FEEDBACK_SESSION_EDITED, StatusMessageColor.SUCCESS);
    assertFalse(pageData.getHasError());
    expectedString = "TEAMMATESLOG|||instructorFeedbackEditSave|||instructorFeedbackEditSave|||true|||" + "Instructor|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1|||" + "instr1@course1.tmt|||Updated Feedback Session " + "<span class=\"bold\">(First feedback session)</span> for Course " + "<span class=\"bold\">[idOfTypicalCourse1]</span> created.<br>" + "<span class=\"bold\">From:</span> 2012-02-01T00:00:00Z" + "<span class=\"bold\"> to</span> 2015-01-01T00:00:00Z<br>" + "<span class=\"bold\">Session visible from:</span> 1970-12-31T00:00:00Z<br>" + "<span class=\"bold\">Results visible from:</span> 2014-05-08T02:00:00Z<br><br>" + "<span class=\"bold\">Instructions:</span> " + "<Text: instructions>|||/page/instructorFeedbackEditSave";
    AssertHelper.assertLogMessageEquals(expectedString, a.getLogMessage());
    ______TS("success: Masquerade mode, manual release results, UTC");
    String adminUserId = "admin.user";
    gaeSimulation.loginAsAdmin(adminUserId);
    params = createParamsForTypicalFeedbackSession(instructor1ofCourse1.courseId, session.getFeedbackSessionName());
    params[19] = Const.INSTRUCTOR_FEEDBACK_RESULTS_VISIBLE_TIME_LATER;
    params[25] = "UTC";
    params = addUserIdToParams(instructor1ofCourse1.googleId, params);
    a = getAction(params);
    ar = getAjaxResult(a);
    pageData = (InstructorFeedbackEditPageData) ar.data;
    statusMessage = pageData.getStatusMessagesToUser().get(0);
    verifyStatusMessage(statusMessage, Const.StatusMessages.FEEDBACK_SESSION_EDITED, StatusMessageColor.SUCCESS);
    assertFalse(pageData.getHasError());
    expectedString = "TEAMMATESLOG|||instructorFeedbackEditSave|||instructorFeedbackEditSave|||true|||" + "Instructor(M)|||Instructor 1 of Course 1|||idOfInstructor1OfCourse1|||" + "instr1@course1.tmt|||Updated Feedback Session " + "<span class=\"bold\">(First feedback session)</span> for Course " + "<span class=\"bold\">[idOfTypicalCourse1]</span> created.<br>" + "<span class=\"bold\">From:</span> 2012-02-01T00:00:00Z" + "<span class=\"bold\"> to</span> 2015-01-01T00:00:00Z<br>" + "<span class=\"bold\">Session visible from:</span> 2012-01-01T00:00:00Z<br>" + "<span class=\"bold\">Results visible from:</span> 1970-01-01T00:00:00Z<br><br>" + "<span class=\"bold\">Instructions:</span> " + "<Text: instructions>|||/page/instructorFeedbackEditSave";
    AssertHelper.assertLogMessageEqualsInMasqueradeMode(expectedString, a.getLogMessage(), adminUserId);
    ______TS("failure: Invalid time zone");
    params[27] = "invalid time zone";
    verifyAssumptionFailure(params);
    ______TS("failure: Null time zone");
    params = ArrayUtils.remove(params, 26);
    params = ArrayUtils.remove(params, 26);
    verifyAssumptionFailure(params);
    ______TS("failure: Invalid grace period");
    params[25] = "12dsf";
    verifyAssumptionFailure(params);
    ______TS("failure: Null grace period");
    params = ArrayUtils.remove(params, 26);
    params = ArrayUtils.remove(params, 26);
    verifyAssumptionFailure(params);
}
Also used : FeedbackSessionAttributes(teammates.common.datatransfer.attributes.FeedbackSessionAttributes) InstructorFeedbackEditPageData(teammates.ui.pagedata.InstructorFeedbackEditPageData) AjaxResult(teammates.ui.controller.AjaxResult) InstructorFeedbackEditSaveAction(teammates.ui.controller.InstructorFeedbackEditSaveAction) InstructorAttributes(teammates.common.datatransfer.attributes.InstructorAttributes) StatusMessage(teammates.common.util.StatusMessage) Test(org.testng.annotations.Test)

Example 53 with StatusMessage

use of teammates.common.util.StatusMessage in project teammates by TEAMMATES.

the class InstructorEditStudentFeedbackSaveAction method checkAdditionalConstraints.

@Override
protected void checkAdditionalConstraints() {
    // check the instructor did not submit responses to questions that he/she should not be able
    // to view during moderation
    InstructorAttributes instructor = logic.getInstructorForGoogleId(courseId, account.googleId);
    int numOfQuestionsToGet = data.bundle.questionResponseBundle.size();
    for (int questionIndx = 1; questionIndx <= numOfQuestionsToGet; questionIndx++) {
        String questionId = getRequestParamValue(Const.ParamsNames.FEEDBACK_QUESTION_ID + "-" + questionIndx);
        if (questionId == null) {
            // we do not throw an error if the question was not present on the page for instructors to edit
            continue;
        }
        FeedbackQuestionAttributes questionAttributes = data.bundle.getQuestionAttributes(questionId);
        if (questionAttributes == null) {
            statusToUser.add(new StatusMessage("The feedback session or questions may have changed " + "while you were submitting. Please check your responses " + "to make sure they are saved correctly.", StatusMessageColor.WARNING));
            isError = true;
            log.warning("Question not found. (deleted or invalid id passed?) id: " + questionId + " index: " + questionIndx);
            continue;
        }
        boolean isGiverVisibleToInstructors = questionAttributes.showGiverNameTo.contains(FeedbackParticipantType.INSTRUCTORS);
        boolean isRecipientVisibleToInstructors = questionAttributes.showRecipientNameTo.contains(FeedbackParticipantType.INSTRUCTORS);
        boolean isResponseVisibleToInstructors = questionAttributes.showResponsesTo.contains(FeedbackParticipantType.INSTRUCTORS);
        if (!isResponseVisibleToInstructors || !isGiverVisibleToInstructors || !isRecipientVisibleToInstructors) {
            isError = true;
            throw new UnauthorizedAccessException("Feedback session [" + feedbackSessionName + "] question [" + questionAttributes.getId() + "] is not accessible " + "to instructor [" + instructor.email + "]");
        }
    }
}
Also used : UnauthorizedAccessException(teammates.common.exception.UnauthorizedAccessException) FeedbackQuestionAttributes(teammates.common.datatransfer.attributes.FeedbackQuestionAttributes) InstructorAttributes(teammates.common.datatransfer.attributes.InstructorAttributes) StatusMessage(teammates.common.util.StatusMessage)

Example 54 with StatusMessage

use of teammates.common.util.StatusMessage in project teammates by TEAMMATES.

the class InstructorFeedbackDeleteAction method execute.

@Override
protected ActionResult execute() {
    String courseId = getRequestParamValue(Const.ParamsNames.COURSE_ID);
    String feedbackSessionName = getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);
    String nextUrl = getRequestParamValue(Const.ParamsNames.NEXT_URL);
    Assumption.assertPostParamNotNull(Const.ParamsNames.COURSE_ID, courseId);
    Assumption.assertPostParamNotNull(Const.ParamsNames.FEEDBACK_SESSION_NAME, feedbackSessionName);
    if (nextUrl == null) {
        nextUrl = Const.ActionURIs.INSTRUCTOR_FEEDBACK_SESSIONS_PAGE;
    }
    gateKeeper.verifyAccessible(logic.getInstructorForGoogleId(courseId, account.googleId), logic.getFeedbackSession(feedbackSessionName, courseId), false, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION);
    logic.deleteFeedbackSession(feedbackSessionName, courseId);
    statusToUser.add(new StatusMessage(Const.StatusMessages.FEEDBACK_SESSION_DELETED, StatusMessageColor.SUCCESS));
    statusToAdmin = "Feedback Session <span class=\"bold\">[" + feedbackSessionName + "]</span> " + "from Course: <span class=\"bold\">[" + courseId + " deleted.";
    return createRedirectResult(nextUrl);
}
Also used : StatusMessage(teammates.common.util.StatusMessage)

Example 55 with StatusMessage

use of teammates.common.util.StatusMessage in project teammates by TEAMMATES.

the class InstructorFeedbackEditCopyAction method execute.

@Override
protected ActionResult execute() throws EntityDoesNotExistException {
    String newFeedbackSessionName = getRequestParamValue(Const.ParamsNames.COPIED_FEEDBACK_SESSION_NAME);
    String[] coursesIdToCopyTo = getRequestParamValues(Const.ParamsNames.COPIED_COURSES_ID);
    String originalFeedbackSessionName = getRequestParamValue(Const.ParamsNames.FEEDBACK_SESSION_NAME);
    String originalCourseId = getRequestParamValue(Const.ParamsNames.COURSE_ID);
    String nextUrl = getRequestParamValue(Const.ParamsNames.NEXT_URL);
    Assumption.assertPostParamNotNull(Const.ParamsNames.COURSE_ID, originalCourseId);
    Assumption.assertPostParamNotNull(Const.ParamsNames.FEEDBACK_SESSION_NAME, originalFeedbackSessionName);
    Assumption.assertPostParamNotNull(Const.ParamsNames.COPIED_FEEDBACK_SESSION_NAME, newFeedbackSessionName);
    if (nextUrl == null) {
        nextUrl = Const.ActionURIs.INSTRUCTOR_FEEDBACK_SESSIONS_PAGE;
    }
    if (coursesIdToCopyTo == null || coursesIdToCopyTo.length == 0) {
        return createAjaxResultWithErrorMessage(Const.StatusMessages.FEEDBACK_SESSION_COPY_NONESELECTED);
    }
    InstructorAttributes instructor = logic.getInstructorForGoogleId(originalCourseId, account.googleId);
    FeedbackSessionAttributes fsa = logic.getFeedbackSession(originalFeedbackSessionName, originalCourseId);
    gateKeeper.verifyAccessible(instructor, logic.getCourse(originalCourseId), Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS);
    gateKeeper.verifyAccessible(instructor, fsa, false);
    try {
        // Check if there are no conflicting feedback sessions in all the courses
        List<String> conflictCourses = filterConflictsInCourses(newFeedbackSessionName, coursesIdToCopyTo);
        if (!conflictCourses.isEmpty()) {
            String commaSeparatedListOfCourses = StringHelper.toString(conflictCourses, ",");
            String errorToUser = String.format(Const.StatusMessages.FEEDBACK_SESSION_COPY_ALREADYEXISTS, newFeedbackSessionName, commaSeparatedListOfCourses);
            return createAjaxResultWithErrorMessage(errorToUser);
        }
        FeedbackSessionAttributes fs = null;
        // TODO: consider doing this as a batch insert
        for (String courseIdToCopyTo : coursesIdToCopyTo) {
            InstructorAttributes instructorForCourse = logic.getInstructorForGoogleId(courseIdToCopyTo, account.googleId);
            gateKeeper.verifyAccessible(instructorForCourse, logic.getCourse(courseIdToCopyTo), Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION);
            fs = logic.copyFeedbackSession(newFeedbackSessionName, courseIdToCopyTo, originalFeedbackSessionName, originalCourseId, instructor.email);
        }
        List<String> courses = Arrays.asList(coursesIdToCopyTo);
        String commaSeparatedListOfCourses = StringHelper.toString(courses, ",");
        statusToUser.add(new StatusMessage(Const.StatusMessages.FEEDBACK_SESSION_COPIED, StatusMessageColor.SUCCESS));
        statusToAdmin = "Copying to multiple feedback sessions.<br>" + "New Feedback Session <span class=\"bold\">(" + fs.getFeedbackSessionName() + ")</span> " + "for Courses: <br>" + commaSeparatedListOfCourses + "<br>" + "<span class=\"bold\">From:</span> " + fs.getStartTime() + "<span class=\"bold\"> to</span> " + fs.getEndTime() + "<br>" + "<span class=\"bold\">Session visible from:</span> " + fs.getSessionVisibleFromTime() + "<br>" + "<span class=\"bold\">Results visible from:</span> " + fs.getResultsVisibleFromTime() + "<br><br>" + "<span class=\"bold\">Instructions:</span> " + fs.getInstructions() + "<br>" + "Copied from <span class=\"bold\">(" + originalFeedbackSessionName + ")</span> for Course " + "<span class=\"bold\">[" + originalCourseId + "]</span> created.<br>";
        // so that the instructor can see the new feedback sessions
        return createAjaxResultWithoutClearingStatusMessage(new InstructorFeedbackEditCopyData(account, sessionToken, Config.getAppUrl(nextUrl).withParam(Const.ParamsNames.ERROR, Boolean.FALSE.toString()).withParam(Const.ParamsNames.USER_ID, account.googleId)));
    } catch (EntityAlreadyExistsException e) {
        // If conflicts are checked above, this will only occur via race condition
        setStatusForException(e, Const.StatusMessages.FEEDBACK_SESSION_EXISTS);
        return createAjaxResultWithErrorMessage(Const.StatusMessages.FEEDBACK_SESSION_EXISTS);
    } catch (InvalidParametersException e) {
        setStatusForException(e);
        return createAjaxResultWithErrorMessage(e.getMessage());
    }
}
Also used : FeedbackSessionAttributes(teammates.common.datatransfer.attributes.FeedbackSessionAttributes) EntityAlreadyExistsException(teammates.common.exception.EntityAlreadyExistsException) InstructorFeedbackEditCopyData(teammates.ui.pagedata.InstructorFeedbackEditCopyData) InvalidParametersException(teammates.common.exception.InvalidParametersException) InstructorAttributes(teammates.common.datatransfer.attributes.InstructorAttributes) StatusMessage(teammates.common.util.StatusMessage)

Aggregations

StatusMessage (teammates.common.util.StatusMessage)81 InstructorAttributes (teammates.common.datatransfer.attributes.InstructorAttributes)34 InvalidParametersException (teammates.common.exception.InvalidParametersException)20 FeedbackSessionAttributes (teammates.common.datatransfer.attributes.FeedbackSessionAttributes)18 ArrayList (java.util.ArrayList)14 StudentAttributes (teammates.common.datatransfer.attributes.StudentAttributes)9 EntityDoesNotExistException (teammates.common.exception.EntityDoesNotExistException)9 CourseAttributes (teammates.common.datatransfer.attributes.CourseAttributes)7 List (java.util.List)6 FeedbackQuestionAttributes (teammates.common.datatransfer.attributes.FeedbackQuestionAttributes)6 EntityAlreadyExistsException (teammates.common.exception.EntityAlreadyExistsException)6 HashMap (java.util.HashMap)4 StudentProfileAttributes (teammates.common.datatransfer.attributes.StudentProfileAttributes)4 UnauthorizedAccessException (teammates.common.exception.UnauthorizedAccessException)3 PageData (teammates.ui.pagedata.PageData)3 BlobInfo (com.google.appengine.api.blobstore.BlobInfo)2 BlobKey (com.google.appengine.api.blobstore.BlobKey)2 BlobstoreFailureException (com.google.appengine.api.blobstore.BlobstoreFailureException)2 Text (com.google.appengine.api.datastore.Text)2 AppLogLine (com.google.appengine.api.log.AppLogLine)2