/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.update.internal; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import de.rcenvironment.core.component.update.api.PersistentComponentDescription; import de.rcenvironment.core.component.update.api.RemotablePersistentComponentDescriptionUpdateService; import de.rcenvironment.core.component.update.api.PersistentDescriptionFormatVersion; import de.rcenvironment.core.component.update.spi.PersistentComponentDescriptionUpdater; import de.rcenvironment.core.utils.common.rpc.RemoteOperationException; import de.rcenvironment.core.utils.common.security.AllowRemoteAccess; /** * Implementation of {@link RemotablePersistentComponentDescriptionUpdateService}. * * @author Doreen Seider */ public class PersistentComponentDescriptionUpdateServiceImpl implements RemotablePersistentComponentDescriptionUpdateService { private Map<String, PersistentComponentDescriptionUpdater> updaters = new HashMap<String, PersistentComponentDescriptionUpdater>(); private Map<Boolean, Map<String, Integer>> versionsToUpdate = new HashMap<Boolean, Map<String, Integer>>(); public PersistentComponentDescriptionUpdateServiceImpl() { versionsToUpdate.put(true, Collections.synchronizedMap(new HashMap<String, Integer>())); versionsToUpdate.put(false, Collections.synchronizedMap(new HashMap<String, Integer>())); } @AllowRemoteAccess @Override public int getFormatVersionsAffectedByUpdate(List<PersistentComponentDescription> descriptions, Boolean silent) throws RemoteOperationException { int updateAvailable = PersistentDescriptionFormatVersion.NONE; if (descriptions != null) { for (PersistentComponentDescription description : descriptions) { PersistentComponentDescriptionUpdater updater = findFirstMatchingUpdater(description.getComponentIdentifier()); if (versionsToUpdate.get(silent).containsKey(getVersionMapIdentifier(description))) { updateAvailable = updateAvailable | versionsToUpdate.get(silent).get(getVersionMapIdentifier(description)); } else if (updater != null) { int update = updater.getFormatVersionsAffectedByUpdate(description.getComponentVersion(), silent); updateAvailable = updateAvailable | update; versionsToUpdate.get(silent).put(getVersionMapIdentifier(description), update); } } } return updateAvailable; } private String getVersionMapIdentifier(PersistentComponentDescription description) { return description.getComponentIdentifier() + description.getComponentVersion(); } private boolean isUpdateNeeded(PersistentComponentDescription description, boolean silent, int formatVersion, PersistentComponentDescriptionUpdater updater) { if (!versionsToUpdate.get(silent).containsKey(getVersionMapIdentifier(description))) { versionsToUpdate.get(silent).put(getVersionMapIdentifier(description), updater.getFormatVersionsAffectedByUpdate(description.getComponentVersion(), silent)); } return (versionsToUpdate.get(silent).get(getVersionMapIdentifier(description)) & formatVersion) == formatVersion; } private PersistentComponentDescriptionUpdater findFirstMatchingUpdater(String compIdentifier) { // iterate over all entries should be fine, because the amount of updaters shouldn't be more than 10 (07/2013) synchronized (updaters) { for (String key : updaters.keySet()) { if (compIdentifier.matches(key)) { // TODO review if 'key' can be still a regular expression here return updaters.get(key); } } } return null; } @AllowRemoteAccess @Override public List<PersistentComponentDescription> performComponentDescriptionUpdates(Integer formatVersion, List<PersistentComponentDescription> descriptions, Boolean silent) throws IOException, RemoteOperationException { List<PersistentComponentDescription> updatedDescriptions = new ArrayList<PersistentComponentDescription>(); for (PersistentComponentDescription description : descriptions) { PersistentComponentDescriptionUpdater updater = findFirstMatchingUpdater(description.getComponentIdentifier()); if (updater != null && isUpdateNeeded(description, silent, formatVersion, updater)) { updatedDescriptions.add(updater.performComponentDescriptionUpdate(formatVersion, description, silent)); } else { updatedDescriptions.add(description); } } return updatedDescriptions; } protected void addPersistentComponentDescriptionUpdater(PersistentComponentDescriptionUpdater updater) { for (String identifier : updater.getComponentIdentifiersAffectedByUpdate()) { synchronized (updaters) { updaters.put(identifier, updater); } } } protected void removePersistentComponentDescriptionUpdater(PersistentComponentDescriptionUpdater updater) { synchronized (updaters) { updaters.remove(updater.getComponentIdentifiersAffectedByUpdate()); } } }