@@ -0,0 +1,3417 @@
+package org.rmatil.sync.network.core;%0A%0Aimport org.rmatil.sync.network.api.ILocationManager;%0Aimport org.rmatil.sync.network.api.IUser;%0Aimport org.rmatil.sync.network.config.Config;%0Aimport org.rmatil.sync.network.core.model.ClientLocation;%0Aimport org.rmatil.sync.network.core.serialize.ByteSerializer;%0Aimport org.rmatil.sync.persistence.api.IStorageAdapter;%0Aimport org.rmatil.sync.persistence.api.StorageType;%0Aimport org.rmatil.sync.persistence.core.dht.DhtPathElement;%0Aimport org.rmatil.sync.persistence.exceptions.InputOutputException;%0A%0Aimport java.io.IOException;%0Aimport java.util.ArrayList;%0Aimport java.util.List;%0A%0A/**%0A * An independent manager which administers client locations%0A * from various users.%0A * Note, that to add or remove a client location to an user, write permission is%0A * ensured by using the public key of the given user.%0A */%0Apublic class LocationManager implements ILocationManager %7B%0A%0A    /**%0A     * A storage adapter giving access to persisted locations%0A     */%0A    protected IStorageAdapter storageAdapter;%0A%0A    public LocationManager(IStorageAdapter storageAdapter) %7B%0A        this.storageAdapter = storageAdapter;%0A    %7D%0A%0A    @Override%0A    public void addClientLocation(IUser user, ClientLocation location)%0A            throws InputOutputException %7B%0A        DhtPathElement dhtPathElement = new DhtPathElement(%0A                Config.DEFAULT.getLocationsLocationKey(),%0A                user.getPublicKey()%0A        );%0A%0A        List%3CClientLocation%3E locations = this.getClientLocations(user);%0A        locations.add(location);%0A%0A        byte%5B%5D bytes;%0A        try %7B%0A            bytes = ByteSerializer.toBytes(locations);%0A        %7D catch (IOException e) %7B%0A            throw new InputOutputException(e);%0A        %7D%0A%0A        this.storageAdapter.persist(StorageType.FILE, dhtPathElement, bytes);%0A    %7D%0A%0A    @Override%0A    public void removeClientLocation(IUser user, ClientLocation location)%0A            throws InputOutputException %7B%0A        // private key must be used to access for write%0A        DhtPathElement dhtPathElement = new DhtPathElement(%0A                Config.DEFAULT.getLocationsLocationKey(),%0A                user.getPublicKey()%0A        );%0A%0A        List%3CClientLocation%3E locations = this.getClientLocations(user);%0A        locations.remove(location);%0A%0A        byte%5B%5D bytes;%0A        try %7B%0A            bytes = ByteSerializer.toBytes(locations);%0A        %7D catch (IOException e) %7B%0A            throw new InputOutputException(e);%0A        %7D%0A%0A        this.storageAdapter.persist(StorageType.FILE, dhtPathElement, bytes);%0A    %7D%0A%0A    @Override%0A    public List%3CClientLocation%3E getClientLocations(IUser user)%0A            throws InputOutputException %7B%0A        DhtPathElement dhtPathElement = new DhtPathElement(%0A                Config.DEFAULT.getLocationsLocationKey(),%0A                user.getPublicKey()%0A        );%0A%0A        byte%5B%5D bytes = this.storageAdapter.read(dhtPathElement);%0A%0A        if (0 == bytes.length) %7B%0A            // there was no element stored in the dht%0A            return new ArrayList%3C%3E();%0A        %7D%0A%0A        List%3CClientLocation%3E locations;%0A        try %7B%0A            locations = (List%3CClientLocation%3E) ByteSerializer.fromBytes(bytes);%0A        %7D catch (IOException %7C ClassNotFoundException e)%7B%0A            throw new InputOutputException(e);%0A        %7D%0A%0A        return locations;%0A    %7D%0A%0A    @Override%0A    public IStorageAdapter getStorageAdapter() %7B%0A        return this.storageAdapter;%0A    %7D%0A%0A%7D%0A

Add missing location manager