package de.persosim.simulator.platform; import java.util.Collection; import java.util.HashSet; import org.globaltester.logging.BasicLogger; import de.persosim.simulator.cardobjects.CardObject; import de.persosim.simulator.cardobjects.CardObjectIdentifier; import de.persosim.simulator.cardobjects.ElementaryFile; import de.persosim.simulator.cardobjects.FileIdentifier; import de.persosim.simulator.cardobjects.Iso7816LifeCycleState; import de.persosim.simulator.cardobjects.MasterFile; import de.persosim.simulator.exception.AccessDeniedException; import de.persosim.simulator.perso.Personalization; /** * This class provides various helper methods which may be useful when operating * on/with personalizations. * * @author slutters * */ public class PersonalizationHelper { /** * This method accepts a {@link Collection} of type {@link Layer} and a * reference type T. It will return a {@link Collection} of type T which is * an intersecting set of the provided {@link Collection} containing all of * its elements matching the provided type T. The returned * {@link Collection} will never be null but may be empty. * * @param layers * the layers to check * @param type * the type to check for * @return the intersecting set */ public static <T> Collection<T> getCompatibleLayers(Collection<Layer> layers, Class<T> type){ HashSet<T> result = new HashSet<>(); for (Layer layer : layers) { if (type.isAssignableFrom(layer.getClass())){ @SuppressWarnings("unchecked") T casted = (T)layer; result.add(casted); } } return result; } /** * This method accepts a {@link Collection} of type {@link Layer} and a * reference type T. It will return the single object of type T if such is * found within the provided {@link Collection}. If there is no such object * null will be returned. If there is more than one object of this type an * IllegalArgumentException will be thrown. * * @param layers * the layers to check * @param type * the type to check for * @return the matching object */ public static <T> T getUniqueCompatibleLayer(Collection<Layer> layers, Class<T> type) { Collection<T> compatibleLayers = PersonalizationHelper.getCompatibleLayers(layers, type); if(compatibleLayers.size() <= 1) { if(compatibleLayers.size() == 1) { return compatibleLayers.iterator().next(); } else{ return null; } } else{ throw new IllegalArgumentException("more than 1 matching layers found"); } } /** * This method recursively sets the card life cycle state for the provided * {@link CardObject} and all of its children to operational activated * * @param objectTree * the root object for which to set the card life cycle state */ public static void setLifeCycleStates(CardObject objectTree) { Collection<CardObject> children = objectTree.getChildren(); if (children.size() > 0){ for (CardObject cardObject : children) { setLifeCycleStates(cardObject); if (cardObject.getLifeCycleState().isPersonalizationPhase()){ try { cardObject.updateLifeCycleState(Iso7816LifeCycleState.OPERATIONAL_ACTIVATED); } catch (AccessDeniedException e) { BasicLogger.logException(PersonalizationHelper.class, e, BasicLogger.WARN); } } } } } /** * Returns the file with the given file identifier under the chosen parent object of a given personalization. * @param perso The {@link Personalization}} to search in. * @param fileIdentifier The file identifier of the file to search. * @param df * the parent object to search in or <code>null</code> if the * root element should be searched * @return the bytes of the found file * @throws AccessDeniedException */ public static byte[] getFileFromPerso(Personalization perso, int fileIdentifier, CardObjectIdentifier df) throws AccessDeniedException { CardObject parent; MasterFile mf = PersonalizationHelper.getUniqueCompatibleLayer(perso.getLayerList(), CommandProcessor.class).getMasterFile(); if (df != null) { Collection<CardObject> parentCandidates = mf.findChildren(df); if (parentCandidates.size() != 1) { throw new IllegalArgumentException("The chosen parent is ambigous"); } parent = parentCandidates.iterator().next(); } else { parent = mf; } Collection<CardObject> file = parent.findChildren(new FileIdentifier(fileIdentifier)); return ((ElementaryFile) file.iterator().next()).getContent(); } }