Java tutorial
/******************************************************************************* * Educational Online Test Delivery System Copyright (c) 2015 American * Institutes for Research * * Distributed under the AIR Open Source License, Version 1.0 See accompanying * file AIR-License-1_0.txt or at http://www.smarterapp.org/documents/ * American_Institutes_for_Research_Open_Source_Software_License.pdf ******************************************************************************/ package org.opentestsystem.delivery.AccValidator.handlers; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import javax.xml.XMLConstants; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.apache.commons.lang.StringUtils; import org.opentestsystem.delivery.AccValidator.Data.AccFamilySubject; import org.opentestsystem.delivery.AccValidator.Data.AccommodationOption; import org.opentestsystem.delivery.AccValidator.Data.AccommodationText; import org.opentestsystem.delivery.AccValidator.Data.MasterResourceAccommodation; import org.opentestsystem.delivery.AccValidator.Data.ResourceFamily; import org.opentestsystem.delivery.AccValidator.Exception.StoringException; import org.opentestsystem.delivery.AccValidator.Exception.ValidationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.CommandFailureException; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.MongoClient; import com.mongodb.MongoClientURI; /** * Handles requests for the application home page. */ public class ValidationHandler { private static final Logger _logger = LoggerFactory.getLogger(ValidationHandler.class); @Value("${XmlValidation.configFilePath}") String _filePath; @Value("${XmlValidation.xsdFilePath}") String _xsdPath; @Value("${mongo.hostname}") String _mongoHostName; @Value("${mongo.portNumber}") String _mongoPort; @Value("${mongo.username}") String _mongoUserName; @Value("${mongo.password}") String _mongoPassword; @Value("${mongo.databasename}") String _mongoDatabaseName; String _nodeName = null; static List<MasterResourceAccommodation> _masterResourceAccommodations = null; static List<ResourceFamily> _resourceFamilies = new ArrayList<ResourceFamily>(); static String _hostName = null; static String _port = null; static String _userName = null; static String _password = null; static String _databaseName = null; static final String EMPTY = ""; public void setDBInfo(String hostName, String port, String user, String password, String databaseName) { this._hostName = hostName; this._port = port; this._userName = user; this._password = password; this._databaseName = databaseName; } public void validateXmlAccs(String filePath, String xsdPath) throws ValidationException { try { InputStream xmlInput = new FileInputStream(new File(filePath)); InputStream xsdInput = new FileInputStream(new File(xsdPath)); String text = null; XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); XMLStreamReader reader = factory.createXMLStreamReader(xmlInput); boolean firstSelect = true; MasterResourceAccommodation masterResource = null; List<MasterResourceAccommodation> resourceFamiltyMasterResourceAccommodations = null; AccommodationText accommodationText = null; List<AccommodationText> accommodationTexts = null; AccommodationOption accommodationOption = null; List<AccommodationOption> accommodationOptions = null; AccFamilySubject familySubject = null; List<AccFamilySubject> familySubjects = null; ResourceFamily resourceFamily = null; List<String> grades = null; while (reader.hasNext()) { int Event = reader.next(); switch (Event) { case XMLStreamConstants.START_ELEMENT: { switch (reader.getLocalName()) { case "MasterResourceFamily": _masterResourceAccommodations = new ArrayList<MasterResourceAccommodation>(); break; case "SingleSelectResource": masterResource = new MasterResourceAccommodation(); accommodationTexts = new ArrayList<AccommodationText>(); accommodationOptions = new ArrayList<AccommodationOption>(); break; case "MultiSelectResource": masterResource = new MasterResourceAccommodation(); accommodationTexts = new ArrayList<AccommodationText>(); accommodationOptions = new ArrayList<AccommodationOption>(); break; case "EditResource": masterResource = new MasterResourceAccommodation(); accommodationTexts = new ArrayList<AccommodationText>(); accommodationOptions = new ArrayList<AccommodationOption>(); break; case "ResourceFamily": masterResource = new MasterResourceAccommodation(); familySubjects = new ArrayList<AccFamilySubject>(); resourceFamily = new ResourceFamily(); accommodationTexts = new ArrayList<AccommodationText>(); accommodationText = new AccommodationText(); resourceFamiltyMasterResourceAccommodations = new ArrayList<MasterResourceAccommodation>(); grades = new ArrayList<String>(); break; case "Subject": familySubject = new AccFamilySubject(); break; case "Selection": if (firstSelect) { masterResource.setHeader(accommodationTexts); accommodationOption = new AccommodationOption(); accommodationTexts = new ArrayList<AccommodationText>(); } else { accommodationOption = new AccommodationOption(); } firstSelect = false; break; case "Text": accommodationText = new AccommodationText(); break; default: break; } break; } case XMLStreamConstants.CHARACTERS: { String nodeValue = getContents(reader.getText()); if (nodeValue.length() > 0) { text = nodeValue; } break; } case XMLStreamConstants.END_ELEMENT: { switch (reader.getLocalName()) { case "Code": if (accommodationOption == null) { if (familySubject == null) { masterResource.setCode(text); } else { familySubject.setCode(text); } } else { accommodationOption.setCode(text); } text = null; break; case "Order": if (accommodationOption == null) { masterResource.setOrder(Integer.valueOf(text)); } else { accommodationOption.setOrder(Integer.valueOf(text)); } text = null; break; case "MutuallyExclusive": accommodationOption.setMutuallyExclusive(true); text = null; break; case "DefaultSelection": masterResource.setDefaultSelection(text); text = null; break; case "Disabled": masterResource.setDisabled(true); text = null; break; case "Language": accommodationText.setLanguage(text); text = null; break; case "Label": accommodationText.setLabel(text); text = null; break; case "Description": accommodationText.setDescription(text); text = null; break; case "Message": accommodationText.setMessage(text); text = null; break; case "Text": accommodationTexts.add(accommodationText); text = null; break; case "Selection": accommodationOption.setText(accommodationTexts); accommodationOptions.add(accommodationOption); accommodationOption = new AccommodationOption(); accommodationTexts = new ArrayList<AccommodationText>(); text = null; break; case "SingleSelectResource": masterResource.setResourceType("SingleSelectResource"); if (accommodationTexts.size() > 0) { masterResource.setHeader(accommodationTexts); } masterResource.setOptions(accommodationOptions); if (resourceFamily == null) { _masterResourceAccommodations.add(masterResource); } else { resourceFamiltyMasterResourceAccommodations.add(masterResource); } masterResource = null; accommodationOption = null; accommodationOption = null; firstSelect = true; text = null; break; case "MultiSelectResource": masterResource.setResourceType("MultiSelectResource"); if (accommodationTexts.size() > 0) { masterResource.setHeader(accommodationTexts); } masterResource.setOptions(accommodationOptions); if (resourceFamily == null) { _masterResourceAccommodations.add(masterResource); } else { resourceFamiltyMasterResourceAccommodations.add(masterResource); } masterResource = null; accommodationOption = null; accommodationOption = null; firstSelect = true; text = null; break; case "EditResource": masterResource.setResourceType("EditResource"); if (accommodationTexts.size() > 0) { masterResource.setHeader(accommodationTexts); } masterResource.setOptions(accommodationOptions); if (resourceFamily == null) { _masterResourceAccommodations.add(masterResource); } else { resourceFamiltyMasterResourceAccommodations.add(masterResource); } masterResource = null; accommodationOption = null; accommodationOption = null; firstSelect = true; text = null; break; case "ResourceFamily": resourceFamily.setSubject(familySubjects); resourceFamily.setGrade(grades); resourceFamily.setMasterResourceAccommodation(resourceFamiltyMasterResourceAccommodations); _resourceFamilies.add(resourceFamily); familySubjects = null; grades = null; resourceFamily = null; resourceFamiltyMasterResourceAccommodations = null; text = null; break; case "Name": familySubject.setName(text); text = null; break; case "Subject": familySubjects.add(familySubject); familySubject = null; text = null; break; case "Grade": grades.add(text); text = null; break; } break; } } } validateRules(_masterResourceAccommodations, _resourceFamilies); // validation against xsd xmlInput = new FileInputStream(new File(filePath)); xsdInput = new FileInputStream(new File(xsdPath)); validateAgainstXSD(xmlInput, xsdInput); } catch (IOException e) { throw new ValidationException("failed", "The xml could not be parsed into objects. The error message is:" + e.getMessage()); } catch (XMLStreamException e) { throw new ValidationException("failed", "The xml could not be parsed into objects. The error message is:" + e.getMessage()); } } /** * @param masterResourceAccommodations * @param resourceFamilies * @throws ValidationException */ private boolean validateRules(List<MasterResourceAccommodation> masterResourceAccommodations, List<ResourceFamily> resourceFamilies) throws ValidationException { HashMap<String, MasterResourceAccommodation> masterResourcesMap = new HashMap<String, MasterResourceAccommodation>(); HashSet<Integer> resourceOrders = new HashSet<Integer>(); for (MasterResourceAccommodation resource : masterResourceAccommodations) { if (masterResourcesMap.containsKey(resource.getCode())) { _logger.error( "Multiple resource with code:" + resource.getCode() + " within MasterResourceFamily."); throw new ValidationException("failed", "Multiple resource with code:" + resource.getCode() + " within MasterResourceFamily."); } // Validating resource code to see if there is any invalid character if (!validateCode(resource.getCode())) { _logger.error("Code contains invalid character ('\"',''','&','<','>',' ') for resource:" + resource.getCode() + " within Masterresourcefamily"); throw new ValidationException("failed", "Code contains invalid character ('\"',''','&','<','>',' ') for resource:" + resource.getCode() + " within Masterresourcefamily"); } if (!validateAccommodationCodes(resource.getCode())) { _logger.error("Code contains invalid character (' ',',',';','\t') for resource:" + resource.getCode() + " within Masterresourcefamily"); throw new ValidationException("failed", "Code contains invalid character (' ',',',';','\t') for resource:" + resource.getCode() + " within Masterresourcefamily"); } // Order must be positive integer if (resource.getOrder() <= 0) { _logger.error("Order must be positive for resource:" + resource.getCode() + " within Masterresourcefamily"); throw new ValidationException("failed", "Order must be positive integer for resource:" + resource.getCode() + " within Masterresourcefamily"); } else { HashSet<Integer> selectionOrders = new HashSet<Integer>(); if (resourceOrders.contains(resource.getOrder())) { _logger.error("Order must not repeat:" + resource.getCode() + " within Masterresourcefamily "); throw new ValidationException("failed", "Order must not repeat:" + resource.getCode() + " within Masterresourcefamily"); } else { resourceOrders.add(resource.getOrder()); } for (AccommodationOption selection : resource.getOptions()) { if (!validateAccommodationCodes(selection.getCode())) { _logger.error("Code contains invalid character (' ',',',';','\t') in Selection code :" + selection.getCode() + "for Resource: " + resource.getCode() + " within Masterresourcefamily"); throw new ValidationException("failed", "Code contains invalid character (' ',',',';','\t') in Selection code :" + selection.getCode() + "for Resource: " + resource.getCode() + " within Masterresourcefamily"); } if (selection.getOrder() <= 0) { _logger.error("Order must be positive for resource:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); throw new ValidationException("failed", "Order must be positive integer for resource:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); } if (selectionOrders.contains(selection.getOrder())) { _logger.error("Order must not repeat:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); throw new ValidationException("failed", "Order must not repeat:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); } else { selectionOrders.add(selection.getOrder()); } List<AccommodationText> accTexts = selection.getText(); if (accTexts != null) { Boolean isValidText = false; for (AccommodationText text : accTexts) { if (text.getLanguage().equalsIgnoreCase("eng")) { isValidText = true; break; } } if (!isValidText) { _logger.error("English is a required language:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); throw new ValidationException("failed", "English is a required language:" + resource.getCode() + " within Masterresourcefamily and selection: " + selection.getCode()); } } } } masterResourcesMap.put(resource.getCode(), resource); } HashMap<String, List<String>> resourceFamilyMap = new HashMap<String, List<String>>(); for (ResourceFamily resourceFamily : resourceFamilies) { /* * 2. The subject and grade(s) for a Resource Family must be defined in * the Resource Family. */ if (resourceFamily.getSubject() == null || resourceFamily.getSubject().size() <= 0) { _logger.error( "ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has no subject defined"); throw new ValidationException("failed", "ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has no subject defined"); } if (resourceFamily.getGrade() == null || resourceFamily.getGrade().size() <= 0) { _logger.error( "ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has no grade defined"); throw new ValidationException("failed", "ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has no grade defined"); } /* * 4. If a Resource Family is defined for a subject-grade combination that * is already defined by a previous Resource Family, The second Resource * Family will be ignored in favor of the settings of the first Resource * Family that covers the particular subject-grade combination. */ String subjectCode = resourceFamily.getSubject().get(0).getCode(); if (!StringUtils.isEmpty(subjectCode) && resourceFamilyMap.containsKey(subjectCode)) { List<String> grades = resourceFamilyMap.get(subjectCode); List<String> newGrades = resourceFamily.getGrade(); List<String> commonGrades = new ArrayList<String>(); if (!grades.isEmpty() && !newGrades.isEmpty()) { for (int i = 0; i < newGrades.size(); i++) { if (grades.contains(newGrades.get(i))) { commonGrades.add(newGrades.get(i)); } } if (!commonGrades.isEmpty()) { _logger.error( "Subject:" + subjectCode + " and grades:" + commonGrades + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " already exists."); throw new ValidationException("failed", "Subject:" + subjectCode + " and grades:" + commonGrades + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " already exists."); } else { List<String> modifiedGrades = new ArrayList<String>(); modifiedGrades.addAll(grades); modifiedGrades.addAll(newGrades); resourceFamilyMap.put(subjectCode, modifiedGrades); } } } else { resourceFamilyMap.put(subjectCode, resourceFamily.getGrade()); } /* * 1. Resource codes and selection codes in Resource Families must be * present in the Master Resource Family. No new resources or selections * can be defined in subesquent Resource Familes. */ HashMap<String, Boolean> resourcesCode = new HashMap<String, Boolean>(); for (MasterResourceAccommodation resource : resourceFamily.getMasterResourceAccommodation()) { MasterResourceAccommodation masterResource = masterResourcesMap.get(resource.getCode()); if (masterResource == null) { _logger.error("Resource code:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " does not exist in master."); throw new ValidationException("failed", "Resource code:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " does not exist in master."); } if (!validateAccommodationCodes(resource.getCode())) { _logger.error("Resource code:" + resource.getCode() + "contains invalid character (' ',',',';','\t') in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); throw new ValidationException("failed", "Resource code:" + resource.getCode() + "contains invalid character (' ',',',';','\t') in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); } // Duplicate resources not allowed if (resourcesCode.containsKey(resource.getCode())) { _logger.error("Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " is duplicated."); throw new ValidationException("failed", "Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " is duplicated."); } else { resourcesCode.put(resource.getCode(), true); } /* * 6. The following things for a resource defined in the Master Resource * Family cannot be overriden: Code, Order Type, Text/Label, * Text/Description. This restriction ensures consistency of the * resource for tabular user interface and file upload formats. Only the * resource default selection can be overridden. */ // header can't be overridden in resource if (resource.getHeader() != null && resource.getHeader().size() > 0) { _logger.error("Header for resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " can't be overridden."); throw new ValidationException("failed", "Header for resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " can't be overridden."); } // order can't be overridden in resource if (resource.getOrder() > 0 && masterResource.getOrder() != resource.getOrder()) { _logger.error("For resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " there is mismatch in order."); throw new ValidationException("failed", "For resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " there is mismatch in order."); } HashMap<String, AccommodationOption> selectionsMap = new HashMap<String, AccommodationOption>(); for (AccommodationOption selection : masterResource.getOptions()) { if (selectionsMap.containsKey(selection.getCode())) { _logger.error("For master resource:" + masterResource.getCode() + "(" + masterResource.getResourceType() + ")" + " has duplicate selection:" + selection.getCode()); throw new ValidationException("failed", "For master resource:" + masterResource.getCode() + "(" + masterResource.getResourceType() + ")" + " has duplicate selection:" + selection.getCode()); } selectionsMap.put(selection.getCode(), selection); } boolean defaultFound = false; HashMap<String, Boolean> resourceFamilySelectionsMap = new HashMap<String, Boolean>(); for (AccommodationOption selection : resource.getOptions()) { if (!validateAccommodationCodes(selection.getCode())) { _logger.error("Code contains invalid character (' ',',',';','\t') in Selection code:(" + selection.getCode() + ") for Resource: (" + resource.getCode() + ")" + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); throw new ValidationException("failed", "Code contains invalid character (' ',',',';','\t') in Selection code :(" + selection.getCode() + ") for Resource: (" + resource.getCode() + ")" + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); } if (resourceFamilySelectionsMap.containsKey(selection.getCode())) { _logger.error("For resource(ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + "):" + resource.getCode() + "(" + resource.getResourceType() + ")" + " has duplicate selection:" + selection.getCode()); throw new ValidationException("failed", "For resource(ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + "):" + resource.getCode() + "(" + resource.getResourceType() + ")" + " has duplicate selection:" + selection.getCode()); } resourceFamilySelectionsMap.put(selection.getCode(), true); String code = selection.getCode(); // Order must be positive integer if (selection.getOrder() != null && selection.getOrder() <= 0) { _logger.error("Order must be positive integer for selection:" + selection.getCode() + " in resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); throw new ValidationException("failed", "Order must be positive integer for selection:" + selection.getCode() + " in resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); } // order can't be overridden in selection if (selection.getOrder() != null && selection.getOrder() != selectionsMap.get(code).getOrder()) { _logger.error("Selection:" + selection.getCode() + "for Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has mismatch in order."); throw new ValidationException("failed", "Selection:" + selection.getCode() + "for Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " has mismatch in order."); } if (!selectionsMap.containsKey(code)) { _logger.error("Selection code:" + selection.getCode() + "for Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " does not exist in master resource."); throw new ValidationException("failed", "Selection code:" + selection.getCode() + "for Resource:" + resource.getCode() + "(" + resource.getResourceType() + ")" + " inside ResourceFamily:" + resourceFamilies.indexOf(resourceFamily) + " does not exist in master resource."); } } // Rami-4. The default selection must appear as one of the resource // selections if (masterResource.getDefaultSelection() != null && !selectionsMap.containsKey(masterResource.getDefaultSelection())) { _logger.error("Default selection:" + masterResource.getDefaultSelection() + " not found in resource:" + masterResource.getCode() + " in MasterResourceFamily"); throw new ValidationException("failed", "Default selection:" + masterResource.getDefaultSelection() + " not found in resource:" + masterResource.getCode() + " in MasterResourceFamily"); } if (resource.getDefaultSelection() != null && !resourceFamilySelectionsMap.containsKey(resource.getDefaultSelection())) { _logger.error("Default selection:" + resource.getDefaultSelection() + " not found in resource:" + resource.getCode() + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); throw new ValidationException("failed", "Default selection:" + resource.getDefaultSelection() + " not found in resource:" + resource.getCode() + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); } if (resource.getDefaultSelection() == null && masterResource.getDefaultSelection() != null && !resourceFamilySelectionsMap.containsKey(masterResource.getDefaultSelection())) { _logger.error("Default selection:" + masterResource.getDefaultSelection() + " from MasterResourceFamily not found in resource:" + resource.getCode() + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); throw new ValidationException("failed", "Default selection:" + masterResource.getDefaultSelection() + " from MasterResourceFamily not found in resource:" + resource.getCode() + " in ResourceFamily:" + resourceFamilies.indexOf(resourceFamily)); } /* * Nothing to validate. 2. If a resource defined in the Master Resource * Family is completely omitted from a Resource Family, then the ART UI * will inherit all text and selection information about the resource * from the Master Resource Family. position defined by the Order * attribute */ /* * Already handled. 3(a). If a resource defined in the Master Resource * Family is also present in a Resource Family, then: a. The code and * English and translated text of the resource cannot be overridden */ /* * Nothing to validate in xml 3(b). The default code and translations * for the resource may be overridden. */ /* * Nothing to validate in xml 3(c). The UI will only display resource * selections that are repeated in the Resource Family for the resource * and will not display any selections that are omitted for the resource * in the Resource Family. This permits configuration of display of only * certain selections and suppression of other selections for the * subject/grade combination of a Resource Family. */ /* * Already handled 3(d). No new codes can be created for a selection in * a Resource Family that are not already provided in the Master * Resource Family. */ /* * No validation required in xml 3(e). All text fields for resource * selections defined in the Master Resource Family can be overridden in * a Resource Family. */ /* * Resource Families modify the behavior of the Master Resource Family * for specific subjects and for specific student grades. The following * rules apply to resource families: */ /* * Nothing to validate in xml 1. Resource families are not strictly * required. If the intent is that all subjects and grades get exactly * the same resources and selections, then the configuration from the * Master REsource Family will be used for all grades and subjects. */ /* * Nothing to validate in xml 3. Resource Families can be defined for * some subjects and grades, but do not have to be provided for every * possible subject and grade. The Master Resource Family will be used * for any subject/grade combination for which there is no Resource * Family defined. nothing to check */ /* * Already checked 5. No new codes can be defined in Resource Families * that are not already defined in the Master Resource Family. Another * way of looking at this is that new resources cannot be defined in * Resource Families, only in the Master Resource Family. */ /* * Already handled 7. The following things for a resource selection * cannot be overridden: Code, Order. Text/Label, Text/Description and * Text/Message can all be overridden for resource selections. */ } } return true; } /** * @param code * @return */ private boolean validateCode(String code) { String invalidChars = "<>& \"'"; try { int firstChar = Integer.parseInt("" + code.charAt(0)); return false; } catch (Exception e) { for (int i = 0; i < invalidChars.length(); i++) { if (code.contains("" + invalidChars.charAt(i))) return false; } return true; } } private void validateAgainstXSD(InputStream xml, InputStream xsd) throws ValidationException { try { SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = factory.newSchema(new StreamSource(xsd)); Validator validator = schema.newValidator(); validator.validate(new StreamSource(xml)); } catch (Exception ex) { throw new ValidationException("failed", "Failed against schema. Error message:" + ex.getMessage()); } } private String getContents(String nodeValue) { StringBuffer sb = new StringBuffer(); if (nodeValue != null) { char[] ch = nodeValue.toCharArray(); for (char c : ch) { if (c == '\t' || c == '\n') { } else { sb.append(c); } } } return sb.toString(); } private Boolean checkWhiteSpaces(String code) { boolean containsWhitespace = false; for (int i = 0; i < code.length() && !containsWhitespace; i++) { if (Character.isWhitespace(code.charAt(i))) { containsWhitespace = true; } } return containsWhitespace; } private Boolean validateAccommodationCodes(String code) { Boolean isValid = true; if (checkWhiteSpaces(code)) { isValid = false; } else { List<String> specialAllowedCharacters = new ArrayList<String>(); specialAllowedCharacters.add("&"); specialAllowedCharacters.add("'"); specialAllowedCharacters.add(">"); specialAllowedCharacters.add("<"); specialAllowedCharacters.add("""); if (code.contains(",")) { isValid = false; } else if (code.contains(";")) { for (String test : specialAllowedCharacters) { if (StringUtils.countMatches(code, ";") > StringUtils.countMatches(code, test)) { isValid = false; break; } } } } return isValid; } /** * @param resourceFamilies */ public void storeResourceFamiliesIntoDB(List<ResourceFamily> resourceFamilies) throws StoringException { DB database = getMongoDBConnection(); DBCollection collection = database.getCollection("resourceFamily"); collection.drop(); String name = null; String language = null; String label = null; String message = null; String description = null; String code = null; Integer order = null; String defaultSelection = null; String resourceType = null; Boolean mutuallyExclusive; Boolean disabled; for (ResourceFamily rf : resourceFamilies) { BasicDBObject resourceFamily = new BasicDBObject(); BasicDBList subjects = new BasicDBList(); List<AccFamilySubject> accFamilySubjects = rf.getSubject(); for (int i = 0; i < accFamilySubjects.size(); i++) { BasicDBObject subject = new BasicDBObject(); AccFamilySubject sub = accFamilySubjects.get(i); code = sub.getCode(); if (code != null) subject.append("code", code); name = sub.getName(); if (name != null) subject.append("name", name); subjects.add(subject); } BasicDBList grade = new BasicDBList(); List<String> dbGrades = rf.getGrade(); for (int j = 0; j < dbGrades.size(); j++) { grade.add(dbGrades.get(j).toString()); } List<MasterResourceAccommodation> accommodations = rf.getMasterResourceAccommodation(); BasicDBList masterResourceAccommodation = new BasicDBList(); for (int k = 0; k < accommodations.size(); k++) { MasterResourceAccommodation mracc = accommodations.get(k); BasicDBObject accommodation = new BasicDBObject(); BasicDBObject header = new BasicDBObject(); BasicDBList headersList = new BasicDBList(); BasicDBList options = new BasicDBList(); List<AccommodationText> headerTexts = mracc.getHeader(); if (headerTexts != null) { for (AccommodationText headerText : headerTexts) { if (headerText != null) { language = headerText.getLanguage(); if (language != null) header.append("language", language); label = headerText.getLabel(); if (label != null) header.append("label", label); message = headerText.getMessage(); if (message != null) header.append("message", message); description = headerText.getDescription(); if (description != null) header.append("description", description); headersList.add(header); } } } code = mracc.getCode(); if (code != null) accommodation.append("code", code); order = mracc.getOrder(); if (order != 0) accommodation.append("order", order); defaultSelection = mracc.getDefaultSelection(); if (defaultSelection != null) accommodation.append("defaultSelection", defaultSelection); if (header.size() > 0) accommodation.append("header", headersList); resourceType = mracc.getResourceType(); if (mracc.getResourceType() != null) accommodation.append("resourceType", resourceType); disabled = mracc.isDisabled(); if (mracc.isDisabled() != false) { accommodation.append("disabled", disabled); } List<AccommodationOption> accOptions = mracc.getOptions(); for (int i = 0; i < accOptions.size(); i++) { AccommodationOption accOption = accOptions.get(i); if (accOption != null) { BasicDBObject option = new BasicDBObject(); code = accOption.getCode(); if (code != null) option.append("code", code); order = accOption.getOrder(); if (order != null && Integer.valueOf(order) != 0) option.append("order", order); mutuallyExclusive = accOption.isMutuallyExclusive(); if (mutuallyExclusive != false) option.append("mutuallyExclusive", mutuallyExclusive); BasicDBList textList = new BasicDBList(); List<AccommodationText> accTexts = accOption.getText(); if (accTexts != null) { for (AccommodationText accText : accTexts) { if (accText != null) { BasicDBObject text = new BasicDBObject(); language = accText.getLanguage(); if (language != null) text.append("language", language); label = accText.getLabel(); if (label != null) text.append("label", label); description = accText.getDescription(); if (description != null) text.append("description", description); message = accText.getMessage(); if (message != null) text.append("message", message); textList.add(text); } if (textList.size() > 0) option.append("text", textList); } } if (option.size() > 0) options.add(option); } } if (options.size() > 0) accommodation.append("options", options); if (accommodation.size() > 0) masterResourceAccommodation.add(accommodation); } resourceFamily.append("subject", subjects); resourceFamily.append("grade", grade); resourceFamily.append("masterResourceAccommodation", masterResourceAccommodation); collection.insert(resourceFamily); } } /** * @param masterResourceAccommodations */ public void storeMasterResourceAccommodationIntoDB( List<MasterResourceAccommodation> masterResourceAccommodations) throws StoringException { String language = null; String label = null; String message = null; String description = null; String code = null; Integer order = null; String defaultSelection = null; String resourceType = null; Boolean mutuallyExclusive; try { DB database = getMongoDBConnection(); DBCollection collection = database.getCollection("masterResourceAccommodation"); collection.drop(); for (MasterResourceAccommodation mracc : masterResourceAccommodations) { BasicDBObject accommodation = new BasicDBObject(); BasicDBList headers = new BasicDBList(); BasicDBObject header = new BasicDBObject(); BasicDBList options = new BasicDBList(); List<AccommodationText> headerTexts = mracc.getHeader(); if (headerTexts != null) { for (AccommodationText headerText : headerTexts) { language = headerText.getLanguage(); if (language != null) header.append("language", language); label = headerText.getLabel(); if (label != null) header.append("label", label); message = headerText.getMessage(); if (message != null) header.append("message", message); description = headerText.getDescription(); if (description != null) header.append("description", description); headers.add(header); } } code = mracc.getCode(); if (code != null) accommodation.append("code", code); order = mracc.getOrder(); if (order != null && Integer.valueOf(order) != 0) accommodation.append("order", order); defaultSelection = mracc.getDefaultSelection(); if (defaultSelection != null) accommodation.append("defaultSelection", defaultSelection); accommodation.append("header", headers); resourceType = mracc.getResourceType(); if (mracc.getResourceType() != null) accommodation.append("resourceType", resourceType); List<AccommodationOption> accOptions = mracc.getOptions(); for (int i = 0; i < accOptions.size(); i++) { AccommodationOption accOption = accOptions.get(i); BasicDBObject option = new BasicDBObject(); code = accOption.getCode(); if (code != null) option.append("code", code); order = accOption.getOrder(); if (order != null) option.append("order", order); mutuallyExclusive = accOption.isMutuallyExclusive(); if (mutuallyExclusive != false) option.append("mutuallyExclusive", mutuallyExclusive); List<AccommodationText> accTexts = accOption.getText(); if (accTexts != null) { BasicDBList textList = new BasicDBList(); for (AccommodationText accText : accTexts) { BasicDBObject text = new BasicDBObject(); language = accText.getLanguage(); if (language != null) text.append("language", language); label = accText.getLabel(); if (label != null) text.append("label", label); description = accText.getDescription(); if (description != null) text.append("description", description); message = accText.getMessage(); if (message != null) text.append("message", message); textList.add(text); } if (textList.size() > 0) option.append("text", textList); } if (option.size() > 0) options.add(option); } if (options.size() > 0) accommodation.append("options", options); if (accommodation != null) collection.insert(accommodation); } } catch (Exception e) { e.printStackTrace(); } } /** * @return */ private DB getMongoDBConnection() throws StoringException { MongoClient mongoClient = null; DB database = null; try { MongoClientURI uri = null; if (!_userName.equalsIgnoreCase(EMPTY) && !_password.equalsIgnoreCase(EMPTY)) { uri = new MongoClientURI("mongodb://" + _userName + ":" + _password + "@" + _hostName + ":" + _port + "/?authSource=" + _databaseName); } else { uri = new MongoClientURI("mongodb://" + _hostName + ":" + _port); } mongoClient = new MongoClient(uri); database = mongoClient.getDB(_databaseName); } catch (UnknownHostException e) { throw new StoringException(e.getMessage()); } catch (CommandFailureException e) { if (e.getCode() == 18) { throw new StoringException("Authentication Exception:Invalid Credentials"); } else { throw new StoringException(e.getMessage()); } } catch (Exception e) { throw new StoringException(e.getMessage()); } return database; } }