All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.deepsense.neptune.clientlibrary.models.impl.properties.JobPropertiesImpl Maven / Gradle / Ivy

There is a newer version: 1.6.1
Show newest version
/**
 * Copyright (c) 2016, CodiLime Inc.
 */

package io.deepsense.neptune.clientlibrary.models.impl.properties;

import io.deepsense.neptune.apiclient.ApiException;
import io.deepsense.neptune.apiclient.model.KeyValueProperty;
import io.deepsense.neptune.clientlibrary.exceptions.common.NeptuneRuntimeException;
import io.deepsense.neptune.clientlibrary.models.JobProperties;
import io.deepsense.neptune.clientlibrary.services.apiservice.ApiService;

import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

public class JobPropertiesImpl extends AbstractMap implements JobProperties {

    private final ApiService apiService;

    private final UUID jobId;

    private final Set> entrySet;

    public JobPropertiesImpl(ApiService apiService, UUID jobId) {
        this.apiService = apiService;
        this.jobId = jobId;
        this.entrySet = new DynamicEntrySetOfProperties();
    }

    @Override
    public Set> entrySet() {
        return entrySet;
    }

    @Override
    public String put(String key, String value) {
        Map properties = getAllProperties();
        String oldValue = properties.put(key, value);

        if (!Objects.equals(oldValue, value)) {
            updateProperties(properties);
        }

        return oldValue;
    }

    @Override
    public String remove(Object key) {
        Map properties = getAllProperties();

        if (properties.containsKey(key)) {
            String oldValue = properties.remove(key);
            updateProperties(properties);
            return oldValue;
        } else {
            return null;
        }
    }

    @Override
    public void putAll(Map m) {
        Map properties = getAllProperties();

        if (!properties.entrySet().containsAll(m.entrySet())) {
            properties.putAll(m);
            updateProperties(properties);
        }
    }

    @Override
    public void replaceAll(BiFunction function) {
        Map propertiesBeforeReplacement = getAllProperties();

        Map propertiesAfterReplacement = new HashMap<>(propertiesBeforeReplacement);
        propertiesAfterReplacement.replaceAll(function);

        if (!propertiesBeforeReplacement.equals(propertiesAfterReplacement)) {
            updateProperties(propertiesAfterReplacement);
        }
    }

    @Override
    public void clear() {
        updateProperties(Collections.emptyMap());
    }

    private Map getAllProperties() {
        try {
            List apiProperties = apiService.getJob(jobId).getProperties();
            return apiProperties.stream().collect(Collectors.toMap(
                    KeyValueProperty::getKey,
                    KeyValueProperty::getValue));
        } catch (ApiException exc) {
            throw new NeptuneRuntimeException("Loading properties failed!", exc);
        }
    }

    private void updateProperties(Map newProperties) {
        try {
            apiService.updateProperties(jobId, newProperties);
        } catch (ApiException exc) {
            throw new NeptuneRuntimeException("Updating properties failed!", exc);
        }
    }

    private class DynamicEntrySetOfProperties extends AbstractSet>
            implements Set> {

        @Override
        public Iterator> iterator() {
            return new DynamicEntrySetOfPropertiesIterator(getAllProperties());
        }

        @Override
        public int size() {
            return getAllProperties().size();
        }

        @Override
        public boolean remove(Object o) {
            Entry entryToRemove = (Entry) o;
            Map properties = getAllProperties();

            if (properties.entrySet().contains(entryToRemove)) {
                properties.entrySet().remove(entryToRemove);
                updateProperties(properties);
                return true;
            } else {
                return false;
            }
        }

        @Override
        public boolean removeAll(Collection c) {
            Collection> entriesToRemove = (Collection>) c;
            Map properties = getAllProperties();

            Collection keysToRemove = existingEntries(entriesToRemove, properties).stream()
                    .map(Entry::getKey)
                    .collect(Collectors.toList());

            if (!keysToRemove.isEmpty()) {
                properties.keySet().removeAll(keysToRemove);
                updateProperties(properties);
                return true;
            } else {
                return false;
            }
        }

        @Override
        public boolean retainAll(Collection c) {
            Collection> entriesToRemove = (Collection>) c;
            Map properties = getAllProperties();

            Set keysToRetain = existingEntries(entriesToRemove, properties).stream()
                    .map(Entry::getKey)
                    .collect(Collectors.toSet());

            if (!keysToRetain.equals(properties.keySet())) {
                properties.keySet().retainAll(keysToRetain);
                updateProperties(properties);
                return true;
            } else {
                return false;
            }
        }

        @Override
        public void clear() {
            JobPropertiesImpl.this.clear();
        }

        private Collection> existingEntries(
                Collection> testedEntries,
                Map map) {
            return testedEntries.stream().filter(map.entrySet()::contains).collect(Collectors.toList());
        }
    }

    private class DynamicEntrySetOfPropertiesIterator implements Iterator> {

        private final Map properties;

        private final Iterator> baseMapIterator;

        public DynamicEntrySetOfPropertiesIterator(Map properties) {
            this.properties = properties;
            this.baseMapIterator = properties.entrySet().iterator();
        }

        @Override
        public boolean hasNext() {
            return baseMapIterator.hasNext();
        }

        @Override
        public Entry next() {

            Entry currentEntry = baseMapIterator.next();

            return new Entry() {

                private final String key = currentEntry.getKey();

                private String value = currentEntry.getValue();

                @Override
                public String getKey() {
                    return currentEntry.getKey();
                }

                @Override
                public String getValue() {
                    return value;
                }

                @Override
                public String setValue(String value) {
                    this.value = value;
                    String oldValue = properties.put(key, value);
                    updateProperties(properties);
                    return oldValue;
                }
            };
        }

        @Override
        public void remove() {
            baseMapIterator.remove();
            updateProperties(properties);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy