/* * Copyright 2012 Shared Learning Collaborative, LLC * * 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 org.slc.sli.dashboard.manager; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.google.gson.Gson; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slc.sli.api.client.SLIClient; import org.slc.sli.dashboard.client.APIClient; import org.slc.sli.dashboard.client.SDKAPIClient; import org.slc.sli.dashboard.entity.ConfigMap; import org.slc.sli.dashboard.entity.GenericEntity; import org.slc.sli.dashboard.util.Constants; /** * * A mock API client. Reads json data from local files, instead of calling an API server. * */ public class MockAPIClient extends SDKAPIClient implements APIClient { private static Logger log = LoggerFactory.getLogger(MockAPIClient.class); private ClassLoader classLoader; // Mock Data Files private static final String MOCK_DATA_DIRECTORY = "mock_data/"; private static final String MOCK_ENROLLMENT_FILE = "school.json"; private static final String MOCK_STUDENTS_FILE = "student.json"; private static final String MOCK_PROGRAMS_FILE = "student_program_association.json"; private static final String MOCK_ASSESSMENT_METADATA_FILE = "assessment_meta_data.json"; private static final String MOCK_ASSESSMENTS_FILE = "assessment.json"; private static final String MOCK_ATTENDANCE_FILE = "attendance.json"; private static final String MOCK_ED_ORG_FILE = "educational_organization.json"; private static final String MOCK_ED_ORG_ASSOC_FILE = "educational_organization_association.json"; private static final String MOCK_SCHOOL_ED_ORG_ASSOC_FILE = "school_educational_organization_association.json"; public MockAPIClient() { this.classLoader = Thread.currentThread().getContextClassLoader(); } public SLIClient getSdkClient() { return null; } @Override public String getId(String token) { return null; } /** * * Mock API client does not support new Staff API call. * */ @Override public GenericEntity getStaffWithEducationOrganization(String token, String id, String organizationCategory) { return this.getEntity(token, getFilename(MOCK_DATA_DIRECTORY + "common/staffInfo.json"), "IT Admin"); } /** * * Mock API client does not support custom data API calls. * */ @Override public ConfigMap getEdOrgCustomData(String token, String id) { return null; } /** * * Mock API client does not support custom data API calls. * */ @Override public void putEdOrgCustomData(String token, String id, ConfigMap configMap) { } @Override public GenericEntity getStudent(final String token, String studentId) { return this.getEntity(token, getFilename(MOCK_DATA_DIRECTORY + token + "/" + MOCK_STUDENTS_FILE), studentId); } @Override public List<GenericEntity> getStudentsForSection(String token, String sectionId) { return getStudents(token, new LinkedList<String>()); } @Override public List<GenericEntity> getStudentsForSectionWithGradebookEntries(final String token, final String sectionId) { return null; } @Override public GenericEntity getStudentWithOptionalFields(String token, String studentId, List<String> optionalFields) { return this.getEntity(token, getFilename(MOCK_DATA_DIRECTORY + "common/" + "student_transcript.json"), studentId); } //@Override public List<GenericEntity> getStudents(final String token, Collection<String> studentIds) { return this.getEntities(token, getFilename(MOCK_DATA_DIRECTORY + token + "/" + MOCK_STUDENTS_FILE), studentIds); } @Override public List<GenericEntity> getSchools(final String token, List<String> schoolIds) { return this .getEntities(token, getFilename(MOCK_DATA_DIRECTORY + token + "/" + MOCK_ENROLLMENT_FILE), schoolIds); } @Override public List<GenericEntity> getAssessmentsForStudent(final String token, String studentId) { // get all assessments in the file. this is very inefficient, since we're reading the whole // file each time, but only // grabbing assmts for one student. not sure of a good way around it at the moment. List<GenericEntity> studentAssmts = this.getEntities(token, getFilename(MOCK_DATA_DIRECTORY + token + "/" + MOCK_ASSESSMENTS_FILE), null); List<GenericEntity> filteredAssmts = new ArrayList<GenericEntity>(); // filter by the student id for (GenericEntity studentAssmt : studentAssmts) { if (studentAssmt.getString(Constants.ATTR_STUDENT_ID).equals(studentId)) { filteredAssmts.add(studentAssmt); } } return filteredAssmts; } /* * We aren't going to bother with this for now. */ @Override public List<GenericEntity> getAttendanceForStudent(String token, String studentId, Map<String, String> params) { return new ArrayList<GenericEntity>(); } @Override public GenericEntity getSession(String token, String sessionId) { GenericEntity session = new GenericEntity(); session.put("beginDate", "2010-01-01"); session.put("endDate", "2011-12-31"); return session; } @Override public List<GenericEntity> getSessions(String token, String schoolId, Map<String, String> params) { return new ArrayList<GenericEntity>(); } @Override public List<GenericEntity> getSessionsForYear(String token, String schoolYear) { return new ArrayList<GenericEntity>(); } @Override public List<GenericEntity> getAcademicRecordsForStudent(String token, String studentId, Map<String, String> params) { return null; } @Override public List<GenericEntity> getAssessments(final String token, List<String> assessmentIds, Map<String, String> params) { return this.getEntities(token, getFilename(MOCK_DATA_DIRECTORY + MOCK_ASSESSMENT_METADATA_FILE), null); } @Override public GenericEntity getParentEducationalOrganization(final String token, GenericEntity edOrgOrSchool) { // Find the parent ed-org's name. String parentEdOrgId = edOrgOrSchool.getString(Constants.ATTR_PARENT_EDORG); return getEducationOrganization(token, parentEdOrgId); } // helper, to find an ed-org entity. private GenericEntity getEducationOrganization(final String token, String id) { List<GenericEntity> allEdOrgs = this.getEntities(token, getFilename(MOCK_DATA_DIRECTORY + token + "/" + MOCK_ED_ORG_FILE), null); if (id == null) { return null; } for (int i = 0; i < allEdOrgs.size(); i++) { if (id.equals(allEdOrgs.get(i).get(Constants.ATTR_ID))) { return allEdOrgs.get(i); } } // an unknown ed-org return null; } /** * Helper function to translate a .json file into object. * TODO: remove this after assessment meta data is switched to use the generic entity */ public static <T> T[] fromFile(String fileName, Class<T[]> c) { BufferedReader bin = null; try { FileReader filein; filein = new FileReader(fileName); bin = new BufferedReader(filein); String s, total; total = ""; while ((s = bin.readLine()) != null) { total += s; } Gson gson = new Gson(); T[] temp = gson.fromJson(total, c); return temp; } catch (IOException e) { System.err.println(e); return null; } finally { try { if (bin != null) { bin.close(); } } catch (Exception e) { System.err.println(e); } } } /** * Get the list of entities identified by the entity id list and authorized for the security * token * * @param token * - the principle authentication token * @param filePath * - the file containing the JSON entities representation * @param entityIds * - the list of entity ids * @return entityList * - the entity list */ public List<GenericEntity> getEntities(final String token, String filePath, Collection<String> entityIds) { // Get all the entities for the user identified by token List<GenericEntity> entities = fromFile(filePath); // Filter entities according to the entity id list List<GenericEntity> filteredEntities = new ArrayList<GenericEntity>(); if (entityIds != null) { for (GenericEntity entity : entities) { if (entityIds.contains(entity.get(Constants.ATTR_ID))) { filteredEntities.add(entity); } } } else { filteredEntities.addAll(entities); } return filteredEntities; } /** * Get the entity identified by the entity id and authorized for the security token * * @param token * - the principle authentication token * @param filePath * - the file containing the JSON entities representation * @param id * - the entity id * @return entity * - the entity entity */ public GenericEntity getEntity(final String token, String filePath, String id) { // Get all the entities for the user identified by token List<GenericEntity> entities = fromFile(filePath); // Select entity identified by id if (id != null) { for (GenericEntity entity : entities) { if (id.equals(entity.get(Constants.ATTR_ID))) { return entity; } } } return null; } /** * In mock data, each student only exists in one section * Retrieves the population hierarchy and returns the section containing the student, populated * with minimal data */ @Override public GenericEntity getSectionHomeForStudent(String token, String studentId) { List<GenericEntity> hierarchy = getSchools(token, null); for (GenericEntity school : hierarchy) { List<LinkedHashMap> courses = school.getList(Constants.ATTR_COURSES); for (LinkedHashMap course : courses) { List<LinkedHashMap> sections = (List<LinkedHashMap>) course.get(Constants.ATTR_SECTIONS); for (LinkedHashMap section : sections) { List<String> studentUIDs = (List<String>) section.get(Constants.ATTR_STUDENT_UIDS); if (studentUIDs.contains(studentId)) { GenericEntity sectionEntity = new GenericEntity(); sectionEntity.put(Constants.ATTR_UNIQUE_SECTION_CODE, section.get(Constants.ATTR_SECTION_NAME)); sectionEntity.put(Constants.ATTR_ID, section.get(Constants.ATTR_SECTION_NAME)); return sectionEntity; } } } } return null; } /** * Returns teacher with only name object, with first, last, middle names, and prefix populated * Token is the username of logged in user, we use it to populate the name */ @Override public GenericEntity getTeacherForSection(String token, String sectionId) { GenericEntity name = new GenericEntity(); name.put(Constants.ATTR_FIRST_NAME, token); name.put(Constants.ATTR_LAST_SURNAME, ""); name.put(Constants.ATTR_MIDDLE_NAME, ""); name.put(Constants.ATTR_PERSONAL_TITLE_PREFIX, "Dr"); GenericEntity teacher = new GenericEntity(); teacher.put(Constants.ATTR_NAME, name); return teacher; } /** * Retrieves an entity list from the specified file * and instantiates from its JSON representation * * @param filePath * - the file path to persist the view component XML string representation * @return entityList * - the generic entity list */ public List<GenericEntity> fromFile(String filePath) { List<GenericEntity> entityList = new ArrayList<GenericEntity>(); BufferedReader reader = null; try { // Read JSON file reader = new BufferedReader(new FileReader(filePath)); StringBuffer jsonBuffer = new StringBuffer(); String line; while ((line = reader.readLine()) != null) { jsonBuffer.append(line); } // Parse JSON Gson gson = new Gson(); List<Map> maps = gson.fromJson(jsonBuffer.toString(), new ArrayList<Map>().getClass()); for (Map<String, Object> map : maps) { entityList.add(new GenericEntity(map)); } } catch (IOException e) { log.error(e.getMessage()); } catch (NullPointerException e) { log.error(e.getMessage()); } finally { try { if (reader != null) { reader.close(); } } catch (Exception e) { log.error(e.getMessage()); } } return entityList; } public String getFilename(String filename) { URL url = classLoader.getResource(filename); return url == null ? null : url.getFile(); } @Override public List<GenericEntity> getCoursesForStudent(String token, String studentId, Map<String, String> params) { return null; } @Override public List<GenericEntity> getTranscriptsForStudent(String token, String studentId, Map<String, String> params) { return null; } @Override public List<GenericEntity> getSectionsForStudent(String token, String studentId, Map<String, String> params) { return null; } @Override public GenericEntity getEntity(String token, String type, String id, Map<String, String> params) { return null; } @Override public List<GenericEntity> getEnrollmentForStudent(final String token, String studentId) { // TODO Auto-generated method stub return null; } @Override public List<GenericEntity> getStudentsWithSearch(String token, String firstName, String lastName, String schoolId) { // TODO Auto-generated method stub return null; } @Override public List<GenericEntity> getEntities(String token, String type, String id, Map<String, String> params) { // TODO Auto-generated method stub return null; } @Override public List<GenericEntity> getParentEducationalOrganizations(String token, List<GenericEntity> educationalOrganizations) { // TODO Auto-generated method stub return null; } /** * Return a url with the sortBy parameter * @param url * @param sortBy * @return */ public String sortBy(String url, String sortBy) { return url + "?sortBy=" + sortBy; }; /** * Return a url with the sortBy and sortOrder parameter * @param url * @param sortBy * @param sortOrder * "descending" or "ascending" * @return */ public String sortBy(String url, String sortBy, String sortOrder) { return url + "?sortBy=" + sortBy + "&sortOrder=" + sortOrder; } public List<GenericEntity> getParentsForStudent(String token, String studentId) { // TODO Auto-generated method stub return null; }; }