/* * Copyright 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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.google.samples.apps.topeka.model.quiz; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import com.google.samples.apps.topeka.helper.ParcelableHelper; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * This abstract class provides general structure for quizzes. * * @see com.google.samples.apps.topeka.model.quiz.QuizType * @see com.google.samples.apps.topeka.widget.quiz.AbsQuizView */ public abstract class Quiz<A> implements Parcelable { private static final String TAG = "Quiz"; public static final Creator<Quiz> CREATOR = new Creator<Quiz>() { @SuppressWarnings("TryWithIdenticalCatches") @Override public Quiz createFromParcel(Parcel in) { int ordinal = in.readInt(); QuizType type = QuizType.values()[ordinal]; try { Constructor<? extends Quiz> constructor = type.getType() .getConstructor(Parcel.class); return constructor.newInstance(in); } catch (InstantiationException e) { performLegacyCatch(e); } catch (IllegalAccessException e) { performLegacyCatch(e); } catch (InvocationTargetException e) { performLegacyCatch(e); } catch (NoSuchMethodException e) { performLegacyCatch(e); } throw new UnsupportedOperationException("Could not create Quiz"); } @Override public Quiz[] newArray(int size) { return new Quiz[size]; } }; private static void performLegacyCatch(Exception e) { Log.e(TAG, "createFromParcel ", e); } private final String mQuestion; private final String mQuizType; private A mAnswer; /** * Flag indicating whether this quiz has already been solved. * It does not give information whether the solution was correct or not. */ private boolean mSolved; protected Quiz(String question, A answer, boolean solved) { mQuestion = question; mAnswer = answer; mQuizType = getType().getJsonName(); mSolved = solved; } protected Quiz(Parcel in) { mQuestion = in.readString(); mQuizType = getType().getJsonName(); mSolved = ParcelableHelper.readBoolean(in); } /** * @return The {@link QuizType} that represents this quiz. */ public abstract QuizType getType(); /** * Implementations need to return a human readable version of the given answer. */ public abstract String getStringAnswer(); public String getQuestion() { return mQuestion; } public A getAnswer() { return mAnswer; } protected void setAnswer(A answer) { mAnswer = answer; } public boolean isAnswerCorrect(A answer) { return mAnswer.equals(answer); } public boolean isSolved() { return mSolved; } public void setSolved(boolean solved) { mSolved = solved; } /** * @return The id of this quiz. */ public int getId() { return getQuestion().hashCode(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { ParcelableHelper.writeEnumValue(dest, getType()); dest.writeString(mQuestion); ParcelableHelper.writeBoolean(dest, mSolved); } @SuppressWarnings("RedundantIfStatement") @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Quiz)) { return false; } Quiz quiz = (Quiz) o; if (mSolved != quiz.mSolved) { return false; } if (!mAnswer.equals(quiz.mAnswer)) { return false; } if (!mQuestion.equals(quiz.mQuestion)) { return false; } if (!mQuizType.equals(quiz.mQuizType)) { return false; } return true; } @Override public int hashCode() { int result = mQuestion.hashCode(); result = 31 * result + mAnswer.hashCode(); result = 31 * result + mQuizType.hashCode(); result = 31 * result + (mSolved ? 1 : 0); return result; } @Override public String toString() { return getType() + ": \"" + getQuestion() + "\""; } }