diff options
author | Jesse Morgan <jesse@jesterpm.net> | 2016-04-09 14:22:20 -0700 |
---|---|---|
committer | Jesse Morgan <jesse@jesterpm.net> | 2016-04-09 15:48:01 -0700 |
commit | 3102d8bce3426d9cf41aeaf201c360d342677770 (patch) | |
tree | 38c4f1e8828f9af9c4b77a173bee0d312b321698 /src/com/p4square/grow/backend/resources | |
parent | bbf907e51dfcf157bdee24dead1d531122aa25db (diff) |
Switching from Ivy+Ant to Maven.
Diffstat (limited to 'src/com/p4square/grow/backend/resources')
6 files changed, 0 insertions, 872 deletions
diff --git a/src/com/p4square/grow/backend/resources/AccountResource.java b/src/com/p4square/grow/backend/resources/AccountResource.java deleted file mode 100644 index 2ac7061..0000000 --- a/src/com/p4square/grow/backend/resources/AccountResource.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; - -import org.restlet.data.Status; -import org.restlet.resource.ServerResource; -import org.restlet.representation.Representation; - -import org.restlet.ext.jackson.JacksonRepresentation; - -import org.apache.log4j.Logger; - -import com.p4square.grow.model.UserRecord; -import com.p4square.grow.provider.Provider; -import com.p4square.grow.provider.ProvidesUserRecords; -import com.p4square.grow.provider.JsonEncodedProvider; - -/** - * Stores a document about a user. - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class AccountResource extends ServerResource { - private static final Logger LOG = Logger.getLogger(AccountResource.class); - - private Provider<String, UserRecord> mUserRecordProvider; - - private String mUserId; - - @Override - public void doInit() { - super.doInit(); - - final ProvidesUserRecords backend = (ProvidesUserRecords) getApplication(); - mUserRecordProvider = backend.getUserRecordProvider(); - - mUserId = getAttribute("userId"); - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - try { - UserRecord result = mUserRecordProvider.get(mUserId); - - if (result == null) { - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - } - - JacksonRepresentation<UserRecord> rep = new JacksonRepresentation<UserRecord>(result); - rep.setObjectMapper(JsonEncodedProvider.MAPPER); - return rep; - - } catch (IOException e) { - setStatus(Status.SERVER_ERROR_INTERNAL); - return null; - } - } - - /** - * Handle PUT requests - */ - @Override - protected Representation put(Representation entity) { - try { - JacksonRepresentation<UserRecord> representation = - new JacksonRepresentation<>(entity, UserRecord.class); - representation.setObjectMapper(JsonEncodedProvider.MAPPER); - UserRecord record = representation.getObject(); - - mUserRecordProvider.put(mUserId, record); - setStatus(Status.SUCCESS_NO_CONTENT); - - } catch (IOException e) { - setStatus(Status.SERVER_ERROR_INTERNAL); - } - - return null; - } -} diff --git a/src/com/p4square/grow/backend/resources/BannerResource.java b/src/com/p4square/grow/backend/resources/BannerResource.java deleted file mode 100644 index 2b9c8e6..0000000 --- a/src/com/p4square/grow/backend/resources/BannerResource.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; - -import org.restlet.data.Status; -import org.restlet.ext.jackson.JacksonRepresentation; -import org.restlet.representation.Representation; -import org.restlet.representation.StringRepresentation; -import org.restlet.resource.ServerResource; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.apache.log4j.Logger; - -import com.p4square.grow.backend.GrowBackend; -import com.p4square.grow.model.Banner; -import com.p4square.grow.provider.JsonEncodedProvider; -import com.p4square.grow.provider.Provider; - -/** - * Fetches or sets the banner string. - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class BannerResource extends ServerResource { - private static final Logger LOG = Logger.getLogger(BannerResource.class); - - public static final ObjectMapper MAPPER = JsonEncodedProvider.MAPPER; - - private Provider<String, String> mStringProvider; - - @Override - public void doInit() { - super.doInit(); - - final GrowBackend backend = (GrowBackend) getApplication(); - mStringProvider = backend.getStringProvider(); - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - String result = null; - try { - result = mStringProvider.get("banner"); - - } catch (IOException e) { - LOG.warn("Exception loading banner: " + e); - } - - if (result == null || result.length() == 0) { - result = "{\"html\":null}"; - } - - return new StringRepresentation(result); - } - - /** - * Handle PUT requests - */ - @Override - protected Representation put(Representation entity) { - try { - JacksonRepresentation<Banner> representation = - new JacksonRepresentation<>(entity, Banner.class); - representation.setObjectMapper(MAPPER); - - Banner banner = representation.getObject(); - - mStringProvider.put("banner", MAPPER.writeValueAsString(banner)); - setStatus(Status.SUCCESS_NO_CONTENT); - - } catch (IOException e) { - setStatus(Status.SERVER_ERROR_INTERNAL); - } - - return null; - } -} diff --git a/src/com/p4square/grow/backend/resources/SurveyResource.java b/src/com/p4square/grow/backend/resources/SurveyResource.java deleted file mode 100644 index 8723ee2..0000000 --- a/src/com/p4square/grow/backend/resources/SurveyResource.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; - -import java.util.Map; -import java.util.HashMap; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.restlet.data.MediaType; -import org.restlet.data.Status; -import org.restlet.ext.jackson.JacksonRepresentation; -import org.restlet.representation.Representation; -import org.restlet.representation.StringRepresentation; -import org.restlet.resource.ServerResource; - -import org.apache.log4j.Logger; - -import com.p4square.grow.backend.GrowBackend; -import com.p4square.grow.model.Question; -import com.p4square.grow.provider.JsonEncodedProvider; -import com.p4square.grow.provider.Provider; - -/** - * This resource manages assessment questions. - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class SurveyResource extends ServerResource { - private static final Logger LOG = Logger.getLogger(SurveyResource.class); - - private static final ObjectMapper MAPPER = JsonEncodedProvider.MAPPER; - - private Provider<String, Question> mQuestionProvider; - private Provider<String, String> mStringProvider; - - private String mQuestionId; - - @Override - public void doInit() { - super.doInit(); - - final GrowBackend backend = (GrowBackend) getApplication(); - mQuestionProvider = backend.getQuestionProvider(); - mStringProvider = backend.getStringProvider(); - - mQuestionId = getAttribute("questionId"); - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - String result = "{}"; - - if (mQuestionId == null) { - // TODO: List all question ids - - } else if (mQuestionId.equals("first")) { - // Get the first question id from db? - Map<?, ?> questionSummary = getQuestionsSummary(); - mQuestionId = (String) questionSummary.get("first"); - - } else if (mQuestionId.equals("count")) { - // Get the first question id from db? - Map<?, ?> questionSummary = getQuestionsSummary(); - - return new StringRepresentation("{\"count\":" + - String.valueOf((Integer) questionSummary.get("count")) + "}"); - } - - if (mQuestionId != null) { - // Get a question by id - Question question = null; - try { - question = mQuestionProvider.get(mQuestionId); - } catch (IOException e) { - LOG.error("IOException loading question: " + e); - } - - if (question == null) { - // 404 - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - } - - JacksonRepresentation<Question> rep = new JacksonRepresentation<>(question); - rep.setObjectMapper(MAPPER); - return rep; - } - - return new StringRepresentation(result); - } - - private Map<?, ?> getQuestionsSummary() { - try { - // TODO: This could be better. Quick fix for provider support. - String json = mStringProvider.get("/questions"); - - if (json != null) { - return MAPPER.readValue(json, Map.class); - } - - } catch (IOException e) { - LOG.info("Exception reading questions summary.", e); - } - - return null; - } -} diff --git a/src/com/p4square/grow/backend/resources/SurveyResultsResource.java b/src/com/p4square/grow/backend/resources/SurveyResultsResource.java deleted file mode 100644 index 7c15cfd..0000000 --- a/src/com/p4square/grow/backend/resources/SurveyResultsResource.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; -import java.util.Map; -import java.util.HashMap; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.restlet.data.MediaType; -import org.restlet.data.Status; -import org.restlet.representation.Representation; -import org.restlet.representation.StringRepresentation; -import org.restlet.resource.ServerResource; - -import org.apache.log4j.Logger; - -import com.p4square.grow.backend.GrowBackend; -import com.p4square.grow.model.Answer; -import com.p4square.grow.model.Question; -import com.p4square.grow.model.RecordedAnswer; -import com.p4square.grow.model.Score; -import com.p4square.grow.model.UserRecord; -import com.p4square.grow.provider.CollectionProvider; -import com.p4square.grow.provider.Provider; - - -/** - * Store the user's answers to the assessment and generate their score. - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class SurveyResultsResource extends ServerResource { - private static final Logger LOG = Logger.getLogger(SurveyResultsResource.class); - - private static final ObjectMapper MAPPER = new ObjectMapper(); - - static enum RequestType { - ASSESSMENT, ANSWER - } - - private CollectionProvider<String, String, String> mAnswerProvider; - private Provider<String, Question> mQuestionProvider; - private Provider<String, UserRecord> mUserRecordProvider; - - private RequestType mRequestType; - private String mUserId; - private String mQuestionId; - - @Override - public void doInit() { - super.doInit(); - - final GrowBackend backend = (GrowBackend) getApplication(); - mAnswerProvider = backend.getAnswerProvider(); - mQuestionProvider = backend.getQuestionProvider(); - mUserRecordProvider = backend.getUserRecordProvider(); - - mUserId = getAttribute("userId"); - mQuestionId = getAttribute("questionId"); - - mRequestType = RequestType.ASSESSMENT; - if (mQuestionId != null) { - mRequestType = RequestType.ANSWER; - } - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - try { - String result = null; - - switch (mRequestType) { - case ANSWER: - result = mAnswerProvider.get(mUserId, mQuestionId); - break; - - case ASSESSMENT: - result = mAnswerProvider.get(mUserId, "summary"); - if (result == null || result.length() == 0) { - result = buildAssessment(); - } - break; - } - - if (result == null) { - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - } - - return new StringRepresentation(result); - } catch (IOException e) { - LOG.error("IOException getting answer: ", e); - setStatus(Status.SERVER_ERROR_INTERNAL); - return null; - } - } - - /** - * Handle PUT requests - */ - @Override - protected Representation put(Representation entity) { - boolean success = false; - - switch (mRequestType) { - case ANSWER: - try { - mAnswerProvider.put(mUserId, mQuestionId, entity.getText()); - mAnswerProvider.put(mUserId, "lastAnswered", mQuestionId); - mAnswerProvider.put(mUserId, "summary", null); - success = true; - - } catch (Exception e) { - LOG.warn("Caught exception putting answer: " + e.getMessage(), e); - } - break; - - default: - setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED); - return null; - } - - if (success) { - setStatus(Status.SUCCESS_NO_CONTENT); - - } else { - setStatus(Status.SERVER_ERROR_INTERNAL); - } - - return null; - } - - /** - * Clear assessment results. - */ - @Override - protected Representation delete() { - boolean success = false; - - switch (mRequestType) { - case ANSWER: - try { - mAnswerProvider.put(mUserId, mQuestionId, null); - mAnswerProvider.put(mUserId, "summary", null); - success = true; - - } catch (Exception e) { - LOG.warn("Caught exception putting answer: " + e.getMessage(), e); - } - break; - - case ASSESSMENT: - try { - mAnswerProvider.put(mUserId, "summary", null); - mAnswerProvider.put(mUserId, "lastAnswered", null); - // TODO Delete answers - - UserRecord record = mUserRecordProvider.get(mUserId); - if (record != null) { - record.setLanding("assessment"); - mUserRecordProvider.put(mUserId, record); - } - - success = true; - - } catch (Exception e) { - LOG.warn("Caught exception putting answer: " + e.getMessage(), e); - } - break; - - default: - setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED); - return null; - } - - if (success) { - setStatus(Status.SUCCESS_NO_CONTENT); - - } else { - setStatus(Status.SERVER_ERROR_INTERNAL); - } - - return null; - - } - - /** - * This method compiles assessment results. - */ - private String buildAssessment() throws IOException { - StringBuilder sb = new StringBuilder("{ "); - - // Last question answered - final String lastAnswered = mAnswerProvider.get(mUserId, "lastAnswered"); - if (lastAnswered != null && lastAnswered.length() > 0) { - sb.append("\"lastAnswered\": \"" + lastAnswered + "\", "); - } - - // Compute score - Map<String, String> row = mAnswerProvider.query(mUserId); - if (row.size() > 0) { - Score score = new Score(); - boolean scoringDone = false; - int totalAnswers = 0; - for (Map.Entry<String, String> c : row.entrySet()) { - if (c.getKey().equals("lastAnswered") || c.getKey().equals("summary")) { - continue; - } - - try { - Question question = mQuestionProvider.get(c.getKey()); - RecordedAnswer userAnswer = MAPPER.readValue(c.getValue(), RecordedAnswer.class); - - if (question == null) { - LOG.warn("Answer for unknown question: " + c.getKey()); - continue; - } - - LOG.debug("Scoring questionId: " + c.getKey()); - scoringDone = !question.scoreAnswer(score, userAnswer); - - } catch (Exception e) { - LOG.error("Failed to score question: {userid: \"" + mUserId + - "\", questionid:\"" + c.getKey() + - "\", userAnswer:\"" + c.getValue() + "\"}", e); - } - - totalAnswers++; - } - - sb.append("\"score\":" + score.getScore()); - sb.append(", \"sum\":" + score.getSum()); - sb.append(", \"count\":" + score.getCount()); - sb.append(", \"totalAnswers\":" + totalAnswers); - sb.append(", \"result\":\"" + score.toString() + "\""); - } - - sb.append(" }"); - String summary = sb.toString(); - - // Persist summary - mAnswerProvider.put(mUserId, "summary", summary); - - return summary; - } -} diff --git a/src/com/p4square/grow/backend/resources/TrainingRecordResource.java b/src/com/p4square/grow/backend/resources/TrainingRecordResource.java deleted file mode 100644 index 51ba56a..0000000 --- a/src/com/p4square/grow/backend/resources/TrainingRecordResource.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.HashMap; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.restlet.data.MediaType; -import org.restlet.data.Status; -import org.restlet.resource.ServerResource; -import org.restlet.representation.Representation; -import org.restlet.representation.StringRepresentation; - -import org.restlet.ext.jackson.JacksonRepresentation; - -import org.apache.log4j.Logger; - -import com.p4square.grow.backend.GrowBackend; - -import com.p4square.grow.model.Chapter; -import com.p4square.grow.model.Playlist; -import com.p4square.grow.model.VideoRecord; -import com.p4square.grow.model.TrainingRecord; - -import com.p4square.grow.provider.CollectionProvider; -import com.p4square.grow.provider.JsonEncodedProvider; -import com.p4square.grow.provider.Provider; -import com.p4square.grow.provider.ProvidesAssessments; -import com.p4square.grow.provider.ProvidesTrainingRecords; - -import com.p4square.grow.model.Score; - -/** - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class TrainingRecordResource extends ServerResource { - private static final Logger LOG = Logger.getLogger(TrainingRecordResource.class); - private static final ObjectMapper MAPPER = JsonEncodedProvider.MAPPER; - - static enum RequestType { - SUMMARY, VIDEO - } - - private Provider<String, TrainingRecord> mTrainingRecordProvider; - private CollectionProvider<String, String, String> mAnswerProvider; - - private RequestType mRequestType; - private String mUserId; - private String mVideoId; - private TrainingRecord mRecord; - - @Override - public void doInit() { - super.doInit(); - - mTrainingRecordProvider = ((ProvidesTrainingRecords) getApplication()).getTrainingRecordProvider(); - mAnswerProvider = ((ProvidesAssessments) getApplication()).getAnswerProvider(); - - mUserId = getAttribute("userId"); - mVideoId = getAttribute("videoId"); - - try { - Playlist defaultPlaylist = ((ProvidesTrainingRecords) getApplication()).getDefaultPlaylist(); - - mRecord = mTrainingRecordProvider.get(mUserId); - if (mRecord == null) { - mRecord = new TrainingRecord(); - mRecord.setPlaylist(defaultPlaylist); - skipAssessedChapters(mUserId, mRecord); - } else { - // Merge the playlist with the most recent version. - mRecord.getPlaylist().merge(defaultPlaylist); - } - - } catch (IOException e) { - LOG.error("IOException loading TrainingRecord: " + e.getMessage(), e); - mRecord = null; - } - - mRequestType = RequestType.SUMMARY; - if (mVideoId != null) { - mRequestType = RequestType.VIDEO; - } - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - JacksonRepresentation<?> rep = null; - - if (mRecord == null) { - setStatus(Status.SERVER_ERROR_INTERNAL); - return null; - } - - switch (mRequestType) { - case VIDEO: - VideoRecord video = mRecord.getPlaylist().find(mVideoId); - if (video == null) { - break; // Fall through and return 404 - } - rep = new JacksonRepresentation<VideoRecord>(video); - break; - - case SUMMARY: - rep = new JacksonRepresentation<TrainingRecord>(mRecord); - break; - } - - if (rep == null) { - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - - } else { - rep.setObjectMapper(JsonEncodedProvider.MAPPER); - return rep; - } - } - - /** - * Handle PUT requests - */ - @Override - protected Representation put(Representation entity) { - if (mRecord == null) { - setStatus(Status.SERVER_ERROR_INTERNAL); - return null; - } - - switch (mRequestType) { - case VIDEO: - try { - JacksonRepresentation<VideoRecord> representation = - new JacksonRepresentation<>(entity, VideoRecord.class); - representation.setObjectMapper(JsonEncodedProvider.MAPPER); - VideoRecord update = representation.getObject(); - VideoRecord video = mRecord.getPlaylist().find(mVideoId); - - if (video == null) { - // TODO: Video isn't on their playlist... - LOG.warn("Skipping video completion for video missing from playlist."); - - } else if (update.getComplete() && !video.getComplete()) { - // Video was newly completed - video.complete(); - mRecord.setLastVideo(mVideoId); - - mTrainingRecordProvider.put(mUserId, mRecord); - } - - setStatus(Status.SUCCESS_NO_CONTENT); - - } catch (Exception e) { - LOG.warn("Caught exception updating training record: " + e.getMessage(), e); - setStatus(Status.SERVER_ERROR_INTERNAL); - } - break; - - default: - setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED); - } - - return null; - } - - private Score getAssessedScore(String userId) throws IOException { - // Get the user's score. - Score assessedScore = new Score(0, 0); - - String summaryString = mAnswerProvider.get(userId, "summary"); - if (summaryString == null) { - throw new IOException("Asked to create training record for unassessed user " + userId); - } - - Map<?,?> summary = MAPPER.readValue(summaryString, Map.class); - - if (summary.containsKey("sum") && summary.containsKey("count")) { - double sum = (Double) summary.get("sum"); - int count = (Integer) summary.get("count"); - assessedScore = new Score(sum, count); - } - - return assessedScore; - } - - /** - * Mark the chapters which the user assessed through as not required. - */ - private void skipAssessedChapters(String userId, TrainingRecord record) { - // Get the user's score. - Score assessedScore = new Score(0, 0); - - try { - assessedScore = getAssessedScore(userId); - } catch (IOException e) { - LOG.error("IOException fetching assessment record for " + userId, e); - return; - } - - // Mark the correct videos as not required. - Playlist playlist = record.getPlaylist(); - - for (Map.Entry<String, Chapter> entry : playlist.getChaptersMap().entrySet()) { - String chapterId = entry.getKey(); - Chapter chapter = entry.getValue(); - boolean required; - - if ("introduction".equals(chapter)) { - // Introduction chapter is always required - required = true; - - } else { - // Chapter required if the floor of the score is <= the chapter's numeric value. - required = assessedScore.floor() <= Score.numericScore(chapterId); - } - - if (!required) { - for (VideoRecord video : chapter.getVideos().values()) { - video.setRequired(required); - } - } - } - } -} diff --git a/src/com/p4square/grow/backend/resources/TrainingResource.java b/src/com/p4square/grow/backend/resources/TrainingResource.java deleted file mode 100644 index 6efdfab..0000000 --- a/src/com/p4square/grow/backend/resources/TrainingResource.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2013 Jesse Morgan - */ - -package com.p4square.grow.backend.resources; - -import java.io.IOException; -import java.util.Map; - -import org.restlet.data.Status; -import org.restlet.resource.ServerResource; -import org.restlet.representation.Representation; -import org.restlet.representation.StringRepresentation; - -import org.apache.log4j.Logger; - -import com.p4square.grow.backend.GrowBackend; -import com.p4square.grow.backend.db.CassandraDatabase; - -import com.p4square.grow.provider.CollectionProvider; -/** - * This resource returns a listing of training items for a particular level. - * - * @author Jesse Morgan <jesse@jesterpm.net> - */ -public class TrainingResource extends ServerResource { - private final static Logger LOG = Logger.getLogger(TrainingResource.class); - - private CollectionProvider<String, String, String> mVideoProvider; - - private String mLevel; - private String mVideoId; - - @Override - public void doInit() { - super.doInit(); - - GrowBackend backend = (GrowBackend) getApplication(); - mVideoProvider = backend.getVideoProvider(); - - mLevel = getAttribute("level"); - mVideoId = getAttribute("videoId"); - } - - /** - * Handle GET Requests. - */ - @Override - protected Representation get() { - String result = null; - - if (mLevel == null) { - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - } - - try { - if (mVideoId == null) { - // Get all videos - // TODO: This could be improved, but this is the quickest way to get - // providers working. - Map<String, String> videos = mVideoProvider.query(mLevel); - if (videos.size() > 0) { - StringBuilder sb = new StringBuilder("{ \"level\": \"" + mLevel + "\""); - sb.append(", \"videos\": ["); - boolean first = true; - for (String value : videos.values()) { - if (!first) { - sb.append(", "); - } - sb.append(value); - first = false; - } - sb.append("] }"); - result = sb.toString(); - } - - } else { - // Get single video - result = mVideoProvider.get(mLevel, mVideoId); - } - - if (result == null) { - // 404 - setStatus(Status.CLIENT_ERROR_NOT_FOUND); - return null; - } - - return new StringRepresentation(result); - - } catch (IOException e) { - LOG.error("IOException fetch video: " + e.getMessage(), e); - setStatus(Status.SERVER_ERROR_INTERNAL); - return null; - } - } -} |