Java tutorial
/* * Copyright 2012-2013 inBloom, Inc. and its affiliates. * * 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.api.security.context.validator; import java.util.*; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.slc.sli.api.security.context.PagingRepositoryDelegate; import org.slc.sli.api.security.context.resolver.EdOrgHelper; import org.slc.sli.api.util.SecurityUtil; import org.slc.sli.common.constants.EntityNames; import org.slc.sli.common.constants.ParameterConstants; import org.slc.sli.common.util.datetime.DateHelper; import org.slc.sli.domain.Entity; import org.slc.sli.domain.NeutralCriteria; import org.slc.sli.domain.NeutralQuery; import org.slc.sli.domain.Repository; /** * Abstract class that all context validators must extend. */ public abstract class AbstractContextValidator implements IContextValidator { @Autowired private DateHelper dateHelper; @Autowired private PagingRepositoryDelegate<Entity> repo; @Autowired protected EdOrgHelper edorgHelper; protected String getFilterDate(boolean useGracePeriod) { return dateHelper.getFilterDate(useGracePeriod); } protected DateTime getNowMinusGracePeriod() { return dateHelper.getNowMinusGracePeriod(); } protected static final Set<String> GLOBAL_WRITE_RESOURCE = new HashSet<String>( Arrays.asList(EntityNames.ASSESSMENT, EntityNames.LEARNING_OBJECTIVE, EntityNames.LEARNING_STANDARD, EntityNames.COMPETENCY_LEVEL_DESCRIPTOR)); protected static final Set<String> SUB_ENTITIES_OF_STUDENT = new HashSet<String>( Arrays.asList(EntityNames.ATTENDANCE, EntityNames.DISCIPLINE_ACTION, EntityNames.STUDENT_ACADEMIC_RECORD, EntityNames.STUDENT_ASSESSMENT, EntityNames.STUDENT_DISCIPLINE_INCIDENT_ASSOCIATION, EntityNames.STUDENT_GRADEBOOK_ENTRY, EntityNames.STUDENT_PARENT_ASSOCIATION, EntityNames.STUDENT_SCHOOL_ASSOCIATION, EntityNames.STUDENT_SECTION_ASSOCIATION, EntityNames.REPORT_CARD)); /** * Determines if the specified type is a sub-entity of student. * * @param type * Type to check is 'below' student. * @return True if the entity hangs off of student, false otherwise. */ protected boolean isSubEntityOfStudent(String type) { return SUB_ENTITIES_OF_STUDENT.contains(type); } protected void addEndDateToQuery(NeutralQuery query, boolean useGracePeriod) { NeutralCriteria endDateCriteria = new NeutralCriteria(ParameterConstants.END_DATE, NeutralCriteria.CRITERIA_GTE, getFilterDate(useGracePeriod)); query.addOrQuery(new NeutralQuery( new NeutralCriteria(ParameterConstants.END_DATE, NeutralCriteria.CRITERIA_EXISTS, false))); query.addOrQuery(new NeutralQuery(endDateCriteria)); } protected static final Set<String> SUB_ENTITIES_OF_STUDENT_SECTION = new HashSet<String>( Arrays.asList(EntityNames.GRADE, EntityNames.STUDENT_COMPETENCY)); /** * Determines if the specified type is a sub-entity of student section association. * * @param type * Type to check is 'below' student section association. * @return True if the entity hangs off of student section association, false otherwise. */ protected boolean isSubEntityOfStudentSectionAssociation(String type) { return SUB_ENTITIES_OF_STUDENT_SECTION.contains(type); } /** * Checks if the DateTime of the first parameter is earlier (or equal to) the second parameter, * comparing only the year, month, and day. * * @param lhs * First DateTime. * @param rhs * Second DateTime. * @return True if first DateTime is before (or equal to) to the second DateTime, false * otherwise. */ protected boolean isLhsBeforeRhs(DateTime lhs, DateTime rhs) { return dateHelper.isLhsBeforeRhs(lhs, rhs); } /** * Parse the String representing a DateTime and return the corresponding DateTime. * * @param convert * String to be converted (of format yyyy-MM-dd). * @return DateTime object. */ protected DateTime getDateTime(String convert) { return DateTime.parse(convert, DateHelper.getDateTimeFormat()); } /** * Convert the DateTime to a String representation. * * @param convert * DateTime to be converted. * @return String representing DateTime (of format yyyy-MM-dd). */ protected String getDateTimeString(DateTime convert) { return convert.toString(DateHelper.getDateTimeFormat()); } /** * Determines if the user is of type 'staff'. * * @return True if user is of type 'staff', false otherwise. */ protected boolean isStaff() { return SecurityUtil.getUserContext() == SecurityUtil.UserContext.STAFF_CONTEXT || SecurityUtil.getUserContext() == SecurityUtil.UserContext.DUAL_CONTEXT; } /** * Determines if the user is of type 'teacher'. * * @return True if user is of type 'teacher', false otherwise. */ protected boolean isTeacher() { return SecurityUtil.getUserContext() == SecurityUtil.UserContext.TEACHER_CONTEXT || SecurityUtil.getUserContext() == SecurityUtil.UserContext.DUAL_CONTEXT; } /** * Determines if the user is of type 'student' or of 'parent'. * * @return True if user is of type 'student' or 'parent', false otherwise. */ protected boolean isStudentOrParent() { // Just return for students now, later we can add funcitonality for parents also return SecurityUtil.isStudent() || SecurityUtil.isParent(); } /** * Determines if the user is of type 'student'. * * @return True if user is of type 'student', false otherwise. */ protected boolean isStudent() { return SecurityUtil.isStudent(); } public boolean isFieldExpired(Map<String, Object> body, String fieldName, boolean useGracePeriod) { return dateHelper.isFieldExpired(body, fieldName, useGracePeriod); } protected Repository<Entity> getRepo() { return this.repo; } /** * Will go through staffEdorgAssociations that are current and get the descendant * edorgs that you have. * * @return a set of the edorgs you are associated to and their children. */ protected Set<String> getStaffEdOrgLineage() { return edorgHelper.getStaffEdOrgsAndChildren(); } protected Set<String> getEdorgDescendents(Set<String> edOrgLineage) { edOrgLineage.addAll(edorgHelper.getChildEdOrgs(edOrgLineage)); return edOrgLineage; } protected Set<String> getEdorgLineage(Set<String> directEdorgs) { Set<String> ancestors = new HashSet<String>(); Set<String> descendants = new HashSet<String>(directEdorgs); for (String edorg : directEdorgs) { ancestors.addAll(fetchParentEdorgs(edorg)); } descendants = getEdorgDescendents(descendants); descendants.addAll(ancestors); return descendants; } /** * Returns the list of student IDs associated to a student or parent actor, * or empty set otherwise * * @return the list of student IDs associated to a student or parent actor, empty set otherwise */ protected Set<String> getDirectStudentIds() { if (isStudentOrParent()) { return SecurityUtil.getSLIPrincipal().getOwnedStudentIds(); } return new HashSet<String>(); } protected Set<String> getStaffCurrentAssociatedEdOrgs() { return edorgHelper.getDirectEdorgs(); } protected Set<String> getStaffEdOrgParents() { Set<String> edorgHiearchy = new HashSet<String>(); Set<String> directEdorgs = getStaffCurrentAssociatedEdOrgs(); edorgHiearchy.addAll(directEdorgs); for (String edorg : directEdorgs) { edorgHiearchy.addAll(fetchParentEdorgs(edorg)); } return edorgHiearchy; } private Set<String> fetchParentEdorgs(String id) { Set<String> parents = new HashSet<String>(); Entity edOrg = getRepo().findOne(EntityNames.EDUCATION_ORGANIZATION, new NeutralQuery( new NeutralCriteria(ParameterConstants.ID, NeutralCriteria.OPERATOR_EQUAL, id, false))); if (edOrg != null) { parents.addAll(edorgHelper.getParentEdOrgs(edOrg)); } return parents; } /** * Performs a query for entities of type 'type' with _id contained in the List of 'ids'. * Iterates through result and peels off String value contained in body.<<field>>. Returns * map of values that were stored in body.<<field>> to the entity id * * @param type * Entity type to query for. * @param ids * List of _ids of entities to query. * @param field * Field (contained in body) to peel off of entities. * @return Map of values stored in entities body.<<field>> to the entity id. */ protected Map<String, Set<String>> getIdsContainedInFieldOnEntities(String type, List<String> ids, String field) { Map<String, Set<String>> matching = new HashMap<String, Set<String>>(); NeutralQuery query = new NeutralQuery( new NeutralCriteria(ParameterConstants.ID, NeutralCriteria.CRITERIA_IN, ids)); Iterable<Entity> entities = getRepo().findAll(type, query); if (entities != null) { for (Entity entity : entities) { Map<String, Object> body = entity.getBody(); if (body.containsKey(field)) { String value = (String) body.get(field); if (!matching.containsKey(value)) { matching.put(value, new HashSet<String>()); } matching.get(value).add(entity.getEntityId()); } } } return matching; } protected void setRepo(PagingRepositoryDelegate<Entity> repo) { this.repo = repo; } /** * Validate that the id list isn't null, contains at least one id, and that the entity types * match. * * @param correctEntityType * @param inputEntityType * @param ids * @return true if the parameters are valid, false otherwise * @throws IllegalArgumentException * if the types don't match */ protected boolean areParametersValid(String correctEntityType, String inputEntityType, Set<String> ids) { return areParametersValid(Arrays.asList(correctEntityType), inputEntityType, ids); } protected boolean areParametersValid(Collection<String> correctEntityTypes, String inputEntityType, Set<String> ids) { if (!correctEntityTypes.contains(inputEntityType)) { throw new IllegalArgumentException(this.getClass() + " cannot validate type " + inputEntityType); } if (ids == null || ids.size() == 0) { return false; } return true; } protected Set<String> getTeacherEdorgLineage() { Set<String> edorgs = getDirectEdorgs(); edorgs = getEdorgLineage(edorgs); return edorgs; } protected Set<String> getDirectEdorgs() { return edorgHelper.getDirectEdorgs(); } /** * Determines if the entity type has global write context. * * @param type * Entity type. * @return True if the entity has global write context, false otherwise. */ protected boolean isGlobalWrite(String type) { return GLOBAL_WRITE_RESOURCE.contains(type); } /** * Gets all staff -> education organization assignment associations for the teacher. * * @return Iterable set of Entities representing StaffEducationOrgAssociation. */ protected Iterable<Entity> getTeacherSchoolAssociations() { NeutralQuery basicQuery = new NeutralQuery(new NeutralCriteria(ParameterConstants.STAFF_REFERENCE, NeutralCriteria.OPERATOR_EQUAL, SecurityUtil.getSLIPrincipal().getEntity().getEntityId())); return repo.findAll(EntityNames.STAFF_ED_ORG_ASSOCIATION, basicQuery); } @Override public Set<String> getValid(String entityType, Set<String> ids) { // Default "fallback" implementation where ids are validated one by one Set<String> validated = validate(entityType, ids); return validated; } protected DateHelper getDateHelper() { return dateHelper; } protected void setDateHelper(DateHelper dateHelper) { this.dateHelper = dateHelper; } protected Set<String> getValidIds(Set<String> ids, Map<String, Set<String>> validIdMap) { Set<String> valid = new HashSet<String>(); for (String id : ids) { Set<String> validIds = validIdMap.get(id); if (validIds != null) { valid.addAll(validIds); } } return valid; } @Override public SecurityUtil.UserContext getContext() { return SecurityUtil.UserContext.NO_CONTEXT; } }