Java tutorial
/******************************************************************************* * Educational Online Test Delivery System * Copyright (c) 2013 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.authoring.testauth.service.impl; import static org.opentestsystem.authoring.testauth.config.TestAuthUtil.safeParseInt; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.opentestsystem.authoring.testauth.domain.BlueprintElement; import org.opentestsystem.authoring.testauth.domain.BlueprintElementValue; import org.opentestsystem.authoring.testauth.domain.CoreStandardPublicationPayloadElement; import org.opentestsystem.authoring.testauth.domain.ItemSelectionAlgorithm; import org.opentestsystem.authoring.testauth.domain.ItemSelectionAlgorithmHelper; import org.opentestsystem.authoring.testauth.domain.Segment; import com.google.common.base.Equivalence; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Iterables; import com.google.common.collect.MapDifference.ValueDifference; import com.google.common.collect.Maps; import com.google.common.collect.Sets; public final class BlueprintHelper { private BlueprintHelper() { // do not instantiate } // define equivalence of Blueprint Elements to Core Standards protected static final Equivalence<BlueprintElement> BLUEPRINT_ELEMENT_EQUIVALENCE = new Equivalence<BlueprintElement>() { @Override protected boolean doEquivalent(final BlueprintElement left, final BlueprintElement right) { return ComparisonChain.start().compare(left.getStandardKey(), right.getStandardKey()) .compare(left.getLevel(), right.getLevel()).compare(left.getGrade(), right.getGrade()) .compare(left.getTextDescription(), right.getTextDescription()).result() == 0; } @Override protected int doHash(final BlueprintElement blueprintElement) { return blueprintElement.hashCode(); } }; protected static final Function<ValueDifference<BlueprintElement>, BlueprintElement> BLUEPRINT_ELEMENT_VALUE_DIFF_TRANS = new Function<ValueDifference<BlueprintElement>, BlueprintElement>() { @Override public BlueprintElement apply(final ValueDifference<BlueprintElement> valueDifference) { final BlueprintElement modifiedBlueprintElement = valueDifference.leftValue(); modifiedBlueprintElement.setStandardKey(valueDifference.rightValue().getStandardKey()); // should already be equal modifiedBlueprintElement.setSortData(valueDifference.rightValue().getSortData()); // should already be equal modifiedBlueprintElement.setLevel(valueDifference.rightValue().getLevel()); modifiedBlueprintElement.setGrade(valueDifference.rightValue().getGrade()); modifiedBlueprintElement.setTextDescription(valueDifference.rightValue().getTextDescription()); return modifiedBlueprintElement; } }; protected static final Function<BlueprintElement, String> BLUEPRINT_ELEMENT_UNIQUE_KEY_FUNCTION = new Function<BlueprintElement, String>() { @Override public String apply(final BlueprintElement blueprintElement) { return blueprintElement.getStandardKey() + ">" + blueprintElement.getGrade(); } }; protected static final Function<BlueprintElement, String> BLUEPRINT_ELEMENT_PARENT_KEY_FUNCTION = new Function<BlueprintElement, String>() { @Override public String apply(final BlueprintElement blueprintElement) { return StringUtils.isEmpty(blueprintElement.getParentKey()) ? null : blueprintElement.getParentKey() + ">" + blueprintElement.getGrade(); } }; protected static final class BPE_BPEV_TRANSFORMER implements Function<BlueprintElement, BlueprintElementValue> { private final String valueKey; public static BPE_BPEV_TRANSFORMER getInstance(final String valueKey) { return new BPE_BPEV_TRANSFORMER(valueKey); } public BPE_BPEV_TRANSFORMER(final String aValueKey) { this.valueKey = aValueKey; } @Override public BlueprintElementValue apply(final BlueprintElement blueprintElement) { return blueprintElement.getBlueprintElementValueMap().get(this.valueKey); } }; protected static final Function<BlueprintElement, String> BLUEPRINT_ELEMENT_GRADE_FUNCTION = new Function<BlueprintElement, String>() { @Override public String apply(final BlueprintElement blueprintElement) { return blueprintElement.getGrade(); } }; protected static final class CORE_STANDARD_BLUEPRINT_ELEMENT_TRANSFORMER implements Function<CoreStandardPublicationPayloadElement, BlueprintElement> { private final String client; public static CORE_STANDARD_BLUEPRINT_ELEMENT_TRANSFORMER getInstance(final String client) { return new CORE_STANDARD_BLUEPRINT_ELEMENT_TRANSFORMER(client); } private CORE_STANDARD_BLUEPRINT_ELEMENT_TRANSFORMER(final String client) { this.client = client; } @Override public BlueprintElement apply(final CoreStandardPublicationPayloadElement csElement) { final BlueprintElement be = new BlueprintElement(); // AK: We have blueprint as "SBAC-ELA-v1:2-W" and need to transform to "SBAC-2-W" // check for presence of publication separated by ':' int pubEndPos = StringUtils.indexOf(csElement.getKey(), ":"); if (pubEndPos > 0) be.setStandardKey( client.concat("-").concat(StringUtils.substring(csElement.getKey(), pubEndPos + 1))); else be.setStandardKey(client.concat("-").concat(csElement.getKey())); //be.setSortData(StringUtils.replace(csElement.getKey(), "|", " ")); be.setSortData(StringUtils.replace(be.getStandardKey(), "|", " ")); // seems that CoreStandards sets parent same as the key, // rather than to one level of standard up // temp solution is to check for such case and fix it here TODO String parent = csElement.getFkParent(); if (parent != null && csElement.getKey().equalsIgnoreCase(parent)) { int lastPipePos = StringUtils.lastIndexOf(parent, "|"); if (lastPipePos > 0) parent = StringUtils.substring(parent, 0, lastPipePos); } if (parent != null) { pubEndPos = StringUtils.indexOf(parent, ":"); if (pubEndPos > 0) parent = client.concat("-").concat(StringUtils.substring(parent, pubEndPos + 1)); } be.setParentKey(parent); be.setLevel(csElement.getTreeLevel()); org.springframework.util.StringUtils.trimAllWhitespace(csElement.getFkGradeLevel()); be.setGrade(csElement.getFkGradeLevel()); be.setTextDescription(csElement.getDescription()); be.setActive(true); return be; } }; protected static final Predicate<BlueprintElement> CORE_STANDARDS_INVALID_BLUEPRINT_FILTER = new Predicate<BlueprintElement>() { @Override public boolean apply(final BlueprintElement blueprintElement) { return !StringUtils.isEmpty(blueprintElement.getGrade()); } }; protected static final class BLUEPRINT_ELEMENT_CLEAR_SEGMENT_VALUE_TRANSFORMER implements Function<BlueprintElement, BlueprintElement> { private final String segmentId; public static BLUEPRINT_ELEMENT_CLEAR_SEGMENT_VALUE_TRANSFORMER getInstance(final String segmentId) { return new BLUEPRINT_ELEMENT_CLEAR_SEGMENT_VALUE_TRANSFORMER(segmentId); } private BLUEPRINT_ELEMENT_CLEAR_SEGMENT_VALUE_TRANSFORMER(final String segmentId) { this.segmentId = segmentId; } @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { if (blueprintElement != null && blueprintElement.getBlueprintElementValueMap() != null && blueprintElement.getBlueprintElementValueMap().get(this.segmentId) != null) { blueprintElement.getBlueprintElementValueMap().get(this.segmentId).setOperationalItemMinValue(0); blueprintElement.getBlueprintElementValueMap().get(this.segmentId).setOperationalItemMaxValue(0); blueprintElement.getBlueprintElementValueMap().get(this.segmentId).setFieldTestItemMinValue(0); blueprintElement.getBlueprintElementValueMap().get(this.segmentId).setFieldTestItemMaxValue(0); } return blueprintElement; } }; protected static final class BLUEPRINT_ELEMENT_INJECT_DEFAULT_VALUES_TRANSFORMER implements Function<BlueprintElement, BlueprintElement> { private final String assessmentId; private final String[] grades; private final Map<String, Segment> segmentIdKeyMap; public static BLUEPRINT_ELEMENT_INJECT_DEFAULT_VALUES_TRANSFORMER getInstance(final String assessmentId, final String[] grades, final Map<String, Segment> segmentIdKeyMap) { return new BLUEPRINT_ELEMENT_INJECT_DEFAULT_VALUES_TRANSFORMER(assessmentId, grades, segmentIdKeyMap); } private BLUEPRINT_ELEMENT_INJECT_DEFAULT_VALUES_TRANSFORMER(final String assessmentId, final String[] grades, final Map<String, Segment> segmentIdKeyMap) { this.assessmentId = assessmentId; this.grades = grades; this.segmentIdKeyMap = segmentIdKeyMap; } @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { blueprintElement.setAssessmentId(this.assessmentId); blueprintElement.setActive(Iterables.any(Arrays.asList(blueprintElement.getGrade()), BLUEPRINT_ELEMENT_GRADE_FILTER.getInstance(this.grades))); if (blueprintElement.getBlueprintElementValueMap() == null) { blueprintElement.setBlueprintElementValueMap(new HashMap<String, BlueprintElementValue>()); } // add any missing segment IDs for (final String segmentId : this.segmentIdKeyMap.keySet()) { if (blueprintElement.getBlueprintElementValueMap().get(segmentId) == null) { blueprintElement.getBlueprintElementValueMap().put(segmentId, new BlueprintElementValue(0, 0, 0, 0)); populateDefaultItemSelectionParameters(blueprintElement, segmentId, this.segmentIdKeyMap.get(segmentId).getItemSelectionAlgorithm()); } } final Set<String> keysToRemove = Sets.newHashSet(); // remove anything not in the current set of segment IDs for (final String blueprintElementMapKey : blueprintElement.getBlueprintElementValueMap().keySet()) { if (!this.segmentIdKeyMap.keySet().contains(blueprintElementMapKey)) { keysToRemove.add(blueprintElementMapKey); } } for (final String keyToRemove : keysToRemove) { blueprintElement.getBlueprintElementValueMap().remove(keyToRemove); } return blueprintElement; } }; protected static final class BLUEPRINT_ELEMENT_UPDATE_ISA_PARAMETERS_TRANSFORMER implements Function<BlueprintElement, BlueprintElement> { private final String segmentId; private final ItemSelectionAlgorithm itemSelectionAlgorithm; public static BLUEPRINT_ELEMENT_UPDATE_ISA_PARAMETERS_TRANSFORMER getInstance(final String segmentId, final ItemSelectionAlgorithm itemSelectionAlgorithm) { return new BLUEPRINT_ELEMENT_UPDATE_ISA_PARAMETERS_TRANSFORMER(segmentId, itemSelectionAlgorithm); } private BLUEPRINT_ELEMENT_UPDATE_ISA_PARAMETERS_TRANSFORMER(final String aSegmentId, final ItemSelectionAlgorithm aItemSelectionAlgorithm) { this.segmentId = aSegmentId; this.itemSelectionAlgorithm = aItemSelectionAlgorithm; } @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { if (blueprintElement != null && blueprintElement.getBlueprintElementValueMap() != null && blueprintElement.getBlueprintElementValueMap().get(this.segmentId) != null) { populateDefaultItemSelectionParameters(blueprintElement, this.segmentId, this.itemSelectionAlgorithm); } return blueprintElement; } }; private static class BLUEPRINT_ELEMENT_GRADE_FILTER implements Predicate<String> { private final String[] grades; private BLUEPRINT_ELEMENT_GRADE_FILTER(final String[] grades) { this.grades = grades; } public static BLUEPRINT_ELEMENT_GRADE_FILTER getInstance(final String[] grades) { return new BLUEPRINT_ELEMENT_GRADE_FILTER(grades); } @Override public boolean apply(final String blueprintElementGrade) { return this.grades != null && blueprintElementGrade != null && Iterables.contains(Arrays.asList(this.grades), blueprintElementGrade); } }; protected static class BLUEPRINT_ELEMENT_FILTER_BY_CHOSEN_GRADES implements Predicate<BlueprintElement> { private final String[] grades; private BLUEPRINT_ELEMENT_FILTER_BY_CHOSEN_GRADES(final String[] grades) { this.grades = grades; } public static BLUEPRINT_ELEMENT_FILTER_BY_CHOSEN_GRADES getInstance(final String[] grades) { return new BLUEPRINT_ELEMENT_FILTER_BY_CHOSEN_GRADES(grades); } @Override public boolean apply(final BlueprintElement blueprintElement) { return Iterables.any(Arrays.asList(blueprintElement.getGrade()), BLUEPRINT_ELEMENT_GRADE_FILTER.getInstance(this.grades)); } }; protected static final Predicate<BlueprintElement> BLUEPRINT_ELEMENT_FILTER_REMOVE = new Predicate<BlueprintElement>() { @Override public boolean apply(final BlueprintElement blueprintElement) { return blueprintElement != null && blueprintElement.getId() != null && blueprintElement.getLevel() == null; } }; protected static final Function<BlueprintElement, BlueprintElement> BLUEPRINT_ELEMENT_REMOVE_TRANSFORMER = new Function<BlueprintElement, BlueprintElement>() { @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { blueprintElement.setLevel(null); return blueprintElement; } }; protected static final class BLUEPRINT_ELEMENT_ADD_DEFAULT_SEGMENT_VALUE_TRANSFORMER implements Function<BlueprintElement, BlueprintElement> { private final String segmentId; private final String segmentIdToClone; private final ItemSelectionAlgorithm itemSelectionAlgorithm; public static BLUEPRINT_ELEMENT_ADD_DEFAULT_SEGMENT_VALUE_TRANSFORMER getInstance(final String segmentId, final String segmentIdToClone, final ItemSelectionAlgorithm itemSelectionAlgorithm) { return new BLUEPRINT_ELEMENT_ADD_DEFAULT_SEGMENT_VALUE_TRANSFORMER(segmentId, segmentIdToClone, itemSelectionAlgorithm); } private BLUEPRINT_ELEMENT_ADD_DEFAULT_SEGMENT_VALUE_TRANSFORMER(final String segmentId, final String segmentIdToClone, final ItemSelectionAlgorithm itemSelectionAlgorithm) { this.segmentId = segmentId; this.segmentIdToClone = segmentIdToClone; this.itemSelectionAlgorithm = itemSelectionAlgorithm; } @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { if (blueprintElement != null && blueprintElement.getBlueprintElementValueMap() != null) { // set min/max values if (this.segmentIdToClone != null) { final BlueprintElementValue blueprintElementValue = blueprintElement .getBlueprintElementValueMap().get(this.segmentIdToClone); if (blueprintElementValue != null) { blueprintElement.getBlueprintElementValueMap().get(this.segmentId) .copyMinMaxValuesToElement(blueprintElementValue); } } else { blueprintElement.getBlueprintElementValueMap().put(this.segmentId, new BlueprintElementValue(0, 0, 0, 0)); populateDefaultItemSelectionParameters(blueprintElement, this.segmentId, this.itemSelectionAlgorithm); } } return blueprintElement; } }; protected static final class BLUEPRINT_ELEMENT_REMOVE_SEGMENT_VALUE_TRANSFORMER implements Function<BlueprintElement, BlueprintElement> { private final String segmentId; public static BLUEPRINT_ELEMENT_REMOVE_SEGMENT_VALUE_TRANSFORMER getInstance(final String segmentId) { return new BLUEPRINT_ELEMENT_REMOVE_SEGMENT_VALUE_TRANSFORMER(segmentId); } private BLUEPRINT_ELEMENT_REMOVE_SEGMENT_VALUE_TRANSFORMER(final String segmentId) { this.segmentId = segmentId; } @Override public BlueprintElement apply(final BlueprintElement blueprintElement) { blueprintElement.getBlueprintElementValueMap().remove(this.segmentId); return blueprintElement; } }; protected static final BlueprintElementValue getListSum(final Collection<BlueprintElementValue> bpValueList) { final BlueprintElementValue sumValue = new BlueprintElementValue(0, 0, 0, 0); for (final BlueprintElementValue nextValue : bpValueList) { sumValue.setOperationalItemMinValue(Math.min( sumValue.getOperationalItemMinValue() + safeParseInt(nextValue.getOperationalItemMinValue()), BlueprintElementValue.MAX_VALUE)); sumValue.setOperationalItemMaxValue(Math.min( sumValue.getOperationalItemMaxValue() + safeParseInt(nextValue.getOperationalItemMaxValue()), BlueprintElementValue.MAX_VALUE)); sumValue.setFieldTestItemMinValue(Math.min( sumValue.getFieldTestItemMinValue() + safeParseInt(nextValue.getFieldTestItemMinValue()), BlueprintElementValue.MAX_VALUE)); sumValue.setFieldTestItemMaxValue(Math.min( sumValue.getFieldTestItemMaxValue() + safeParseInt(nextValue.getFieldTestItemMaxValue()), BlueprintElementValue.MAX_VALUE)); } return sumValue; } protected static final BlueprintElementValue calculateDifference(final BlueprintElementValue left, final BlueprintElementValue right) { final BlueprintElementValue calculatedValue = new BlueprintElementValue(); calculatedValue.setOperationalItemMinValue( Math.max(left.getOperationalItemMinValue() - right.getOperationalItemMinValue(), 0)); calculatedValue.setOperationalItemMaxValue( Math.max(left.getOperationalItemMaxValue() - right.getOperationalItemMaxValue(), 0)); calculatedValue.setFieldTestItemMinValue( Math.max(left.getFieldTestItemMinValue() - right.getFieldTestItemMinValue(), 0)); calculatedValue.setFieldTestItemMaxValue( Math.max(left.getFieldTestItemMaxValue() - right.getFieldTestItemMaxValue(), 0)); return calculatedValue; } private static final void populateDefaultItemSelectionParameters(final BlueprintElement blueprintElement, final String segmentId, final ItemSelectionAlgorithm itemSelectionAlgorithm) { if (itemSelectionAlgorithm != null && itemSelectionAlgorithm.getBlueprintParameters() != null) { blueprintElement.getBlueprintElementValueMap().get(segmentId) .setItemSelectionParameters(Maps.transformValues( Maps.uniqueIndex(itemSelectionAlgorithm.getBlueprintParameters(), ItemSelectionAlgorithmHelper.ISA_PARAMETER_NAME_TRANSFORMER), ItemSelectionAlgorithmHelper.ISA_PARAMETER_DEFAULT_VALUE_TRANSFORMER)); } else { blueprintElement.getBlueprintElementValueMap().get(segmentId).setItemSelectionParameters(null); } } protected static final Function<BlueprintElement, String> BP_ELEMENT_ID_TRANSFORMER = new Function<BlueprintElement, String>() { @Override public String apply(final BlueprintElement blueprintElement) { return blueprintElement.getId(); } }; protected static final Predicate<BlueprintElement> BP_ELEMENT_ID_INACTIVE_FILTER = new Predicate<BlueprintElement>() { @Override public boolean apply(final BlueprintElement blueprintElement) { return !blueprintElement.isActive(); } }; }