/* * 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.sample.transform; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.slc.sli.sample.entities.AcademicSubjectType; import org.slc.sli.sample.entities.ComplexObjectType; import org.slc.sli.sample.entities.ContentStandardType; import org.slc.sli.sample.entities.GradeLevelType; import org.slc.sli.sample.entities.InterchangeAssessmentMetadata; import org.slc.sli.sample.entities.LearningObjective; import org.slc.sli.sample.entities.LearningStandard; import org.slc.sli.sample.entities.LearningStandardId; public class CcsCsv2XmlTransformer { private CcsCsvReader ccsCsvReader; private DotNotationToId dotNotationToId; private LearningObjectiveGenerator learningObjectiveGenerator; private GradeLevelMapper gradeLevelMapper; private String outputLocation; private AcademicSubjectType academicSubjectType; private boolean ignoreNonExistentGuid; CcsCsv2XmlTransformer() {} void setCcsCsvReader(CcsCsvReader ccsCsvReader) { this.ccsCsvReader = ccsCsvReader; } void setDotNotationToId(DotNotationToId dotNotationToId) { this.dotNotationToId = dotNotationToId; } void setOutputLocation(String outputLocation) { this.outputLocation = outputLocation; } void setAcademicSubjectType(AcademicSubjectType academicSubjectType) { this.academicSubjectType = academicSubjectType; } void setIgnoreNonExistentGuid(boolean ignoreNonExistentGuid) { this.ignoreNonExistentGuid = ignoreNonExistentGuid; } void setLearningObjectiveGenerator(LearningObjectiveGenerator learningObjectiveGenerator) { this.learningObjectiveGenerator = learningObjectiveGenerator; } void setGradeLevelMapper(GradeLevelMapper gradeLevelMapper) { this.gradeLevelMapper = gradeLevelMapper; } static abstract class DotNotationToId { abstract String getId(String dotNotation); } static abstract class LearningObjectiveGenerator { abstract Collection<LearningObjective> generateLearningObjectives( Map<String, Collection<LearningStandardResult>> learningObjectiveIdToLearningStandardResults, Map<String, String> idToGuidMap) throws IOException; } String getCopyright() { if(ccsCsvReader != null) { return ccsCsvReader.getCopyright(); } return null; } private String getCopyrightXmlComment() { return "\n<!--\n\t"+ getCopyright().replace(">", "") + "\n-->"; } /** * Iterate through common core standard csv records in the CSV files, * converts them into JAXB java objects, and then marshals them into SLI-EdFi xml file. * * @throws JAXBException */ void printLearningStandards() throws JAXBException, IOException { Map<String, Collection<LearningStandardResult>> learningObjectiveIdToLearningStandardResults = new HashMap<String, Collection<LearningStandardResult>>(); InterchangeAssessmentMetadata interchangeAssessmentMetadata = new InterchangeAssessmentMetadata(); List<ComplexObjectType> learningStandards = interchangeAssessmentMetadata.getAssessmentFamilyOrAssessmentOrAssessmentPeriodDescriptor(); int learningStandardCounter = 0; while(ccsCsvReader.getCurrentRecord() != null) { LearningStandardResult learningStandardResult = getLearningStandard(); if(learningStandardResult == null) { ccsCsvReader.getNextRecord(); continue; } LearningStandard learningStandard = learningStandardResult.getLearningStandard(); if(learningStandard != null) { learningStandards.add(learningStandard); String learningObjectiveId = learningStandardResult.getId(); learningObjectiveId = learningObjectiveId.substring(0, learningObjectiveId.lastIndexOf('.')); if(learningObjectiveIdToLearningStandardResults.get(learningObjectiveId) == null) { learningObjectiveIdToLearningStandardResults.put(learningObjectiveId, new ArrayList<LearningStandardResult>()); } learningObjectiveIdToLearningStandardResults.get(learningObjectiveId).add(learningStandardResult); ccsCsvReader.getNextRecord(); learningStandardCounter++; } else { ccsCsvReader.getNextRecord(); continue; } } Collection<LearningObjective> learningObjectives = learningObjectiveGenerator.generateLearningObjectives(learningObjectiveIdToLearningStandardResults, IdToGuidMapper.getInstance().getIdToGuidMap()); Collection<String> learningObjectiveIds = new HashSet<String>(); Collection<String> learningObjectiveText = new HashSet<String>(); for(LearningObjective learningObjective : learningObjectives) { if(learningObjective.getLearningObjectiveId().getIdentificationCode() != null) learningObjectiveIds.add(learningObjective.getLearningObjectiveId().getIdentificationCode().trim()); if(learningObjective.getObjective() != null) { learningObjectiveText.add(learningObjective.getObjective().trim()); } } learningStandards.addAll(learningObjectives); JAXBContext context = JAXBContext.newInstance(LearningStandard.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", getCopyrightXmlComment()); marshaller.setProperty("jaxb.formatted.output", Boolean.TRUE); marshaller.marshal(interchangeAssessmentMetadata, new PrintStream(new File(outputLocation), "UTF-8")); System.out.println("Total " + learningStandardCounter + " LearningStandards are exported."); System.out.println("Total " + learningObjectiveIdToLearningStandardResults.keySet().size() + " LearningObjectives are exported"); System.out.println("Total Learning Objective IDs = " + learningObjectiveIds.size()); System.out.println("Total Learning Objective Texts = " + learningObjectiveText.size()); } GradeLevelType getGradeLevel(int intGradeLevel) { GradeLevelType gradeLevel; switch (intGradeLevel) { case 0: gradeLevel = GradeLevelType.KINDERGARTEN; break; case 1: gradeLevel = GradeLevelType.FIRST_GRADE; break; case 2: gradeLevel = GradeLevelType.SECOND_GRADE; break; case 3: gradeLevel = GradeLevelType.THIRD_GRADE; break; case 4: gradeLevel = GradeLevelType.FOURTH_GRADE; break; case 5: gradeLevel = GradeLevelType.FIFTH_GRADE; break; case 6: gradeLevel = GradeLevelType.SIXTH_GRADE; break; case 7: gradeLevel = GradeLevelType.SEVENTH_GRADE; break; case 8: gradeLevel = GradeLevelType.EIGHTH_GRADE; break; case 9: gradeLevel = GradeLevelType.NINTH_GRADE; break; case 10: gradeLevel = GradeLevelType.TENTH_GRADE; break; case 11: gradeLevel = GradeLevelType.ELEVENTH_GRADE; break; case 12: gradeLevel = GradeLevelType.TWELFTH_GRADE; break; default: throw new RuntimeException("Should never reach here"); } return gradeLevel; } static class LearningStandardResult { private LearningStandard learningStandard; private String id; private String category; private String subCategory; public LearningStandard getLearningStandard() { return learningStandard; } public void setLearningStandard(LearningStandard learningStandard) { this.learningStandard = learningStandard; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } private String getSubCategory() { return subCategory; } public void setSubCategory(String subCategory) { this.subCategory = subCategory; } } private LearningStandardResult getLearningStandard() throws IOException { Map<String, String> learningStandardRecord = ccsCsvReader.getCurrentRecord(); String dotNotation = learningStandardRecord.get("ID"); String id = dotNotationToId.getId(dotNotation); String guid = IdToGuidMapper.getInstance().getGuid(id); if(guid == null) { System.out.println("Dot Notation = <" + dotNotation + ">" + " ID = <" + id + "> does not have guid. State Standard = <" + learningStandardRecord.get("State Standard") + ">"); if(ignoreNonExistentGuid) { return null; } } LearningStandardId learningStandardId = new LearningStandardId(); learningStandardId.setIdentificationCode(guid); LearningStandard learningStandard = new LearningStandard(); learningStandard.setLearningStandardId(learningStandardId); learningStandard.setContentStandard(ContentStandardType.STATE_STANDARD); String description = learningStandardRecord.get("State Standard"); if (description == null || description.equals("")) { System.out.println("no description for" + id); } learningStandard.setDescription(description); learningStandard.setGradeLevel(getGradeLevel(gradeLevelMapper.getGradeLevel(dotNotation))); learningStandard.setSubjectArea(academicSubjectType); LearningStandardResult learningStandardResult = new LearningStandardResult(); learningStandardResult.setId(id); learningStandardResult.setLearningStandard(learningStandard); learningStandardResult.setCategory(learningStandardRecord.get("Category")); learningStandardResult.setSubCategory(learningStandardRecord.get("Sub Category")); return learningStandardResult; } static abstract class GradeLevelMapper { abstract int getGradeLevel(String dotNotation); } static class IdToGuidMapper { private final String identifiersCSVFile = "data/E0330_ccss_identifiers.csv"; private Map<String, String> idToGuid = null; private static IdToGuidMapper instance = new IdToGuidMapper(); private IdToGuidMapper() {} static synchronized IdToGuidMapper getInstance() throws IOException { if(instance == null) { instance = new IdToGuidMapper(); } return instance; } String getGuid(String id) throws IOException { if(idToGuid == null) { loadData(); } return idToGuid.get(id); } Map<String, String> getIdToGuidMap() throws IOException { if (idToGuid == null) { loadData(); } return idToGuid; } private void loadData() throws IOException { idToGuid = new HashMap<String, String>(); CcsCsvReader reader = new CcsCsvReader(); reader.setFileLocation(identifiersCSVFile); reader.load(); while (reader.getCurrentRecord() != null) { Map<String, String> currentRecord = reader.getCurrentRecord(); idToGuid.put(currentRecord.get("Dot notation"), currentRecord.get("GUID")); reader.getNextRecord(); } } } }