001package org.intellimate.izou.identification;
002
003import org.apache.logging.log4j.LogManager;
004import org.apache.logging.log4j.Logger;
005
006import java.util.ArrayList;
007import java.util.Collections;
008import java.util.List;
009import java.util.Optional;
010
011/**
012 * You can register an Object with the IdentificationManager and receive an Identification Objects.
013 */
014//FIXME: ConcurrentModification Exception with streams
015public final class IdentificationManager implements IdentificationManagerM {
016    private List<Identifiable> identifiables = Collections.synchronizedList(new ArrayList<>());
017    private static IdentificationManager ourInstance = new IdentificationManager();
018    private final Logger fileLogger = LogManager.getLogger(this.getClass());
019
020    public static IdentificationManagerM getInstance() {
021        return ourInstance;
022    }
023
024    private IdentificationManager() {
025
026    }
027
028    /**
029     * If you have registered with an Identifiable interface, you can receive Identification Instances with this method.
030     * @param identifiable the registered Identifiable
031     * @return an Identification Instance or null if not registered
032     */
033    @Override
034    public Optional<Identification> getIdentification(Identifiable identifiable) {
035        if(identifiables.stream()
036                .anyMatch(listIdentifiable -> listIdentifiable.getID().equals(identifiable.getID()))) {
037            return Optional.of(Identification.createIdentification(identifiable, true));
038        }
039        return Optional.empty();
040    }
041
042    /**
043     * If a class has registered with an Identifiable interface you can receive an Identification Instance describing
044     * the class by providing his ID.
045     * @param id the ID of the registered Identifiable
046     * @return an Identification Instance or null if not registered
047     */
048    @Override
049    public Optional<Identification> getIdentification(String id) {
050        Optional<Identifiable> result = identifiables.stream()
051                .filter(identifiable1 -> identifiable1.getID().equals(id))
052                .findFirst();
053
054        if(!result.isPresent()) {
055            return Optional.empty();
056        } else {
057            return Optional.of(Identification.createIdentification(result.get()));
058        }
059    }
060
061    /**
062     * Registers an Identifiable, ID has to be unique.
063     * @param identifiable the Identifiable to register
064     * @return true if registered/already registered or false if the ID is already existing
065     */
066    @Override
067    public synchronized boolean registerIdentification(Identifiable identifiable) {
068        if (identifiable == null || identifiable.getID() == null || identifiable.getID().isEmpty()) return false;
069        if (identifiables.contains(identifiable)  || identifiables.stream()
070                .anyMatch(identifiableS -> identifiableS.getID().equals(identifiable.getID())))
071            return false;
072        identifiables.add(identifiable);
073        return true;
074    }
075}