Package nodebox.function

Source Code of nodebox.function.FunctionRepository

package nodebox.function;

import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import nodebox.node.Node;
import nodebox.node.Port;

import java.util.*;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
* Manages a collection of function libraries.
*/
public class FunctionRepository {

    public static FunctionRepository of(FunctionLibrary... libraries) {
        ImmutableSet.Builder<FunctionLibrary> librarySet = ImmutableSet.builder();
        librarySet.addAll(ImmutableSet.copyOf(libraries));
        // The core library is always included.
        librarySet.add(CoreFunctions.LIBRARY);

        ImmutableMap.Builder<String, FunctionLibrary> builder = ImmutableMap.builder();
        for (FunctionLibrary library : librarySet.build()) {
            builder.put(library.getNamespace(), library);
        }
        return new FunctionRepository(builder.build());
    }

    public static FunctionRepository combine(FunctionRepository... repositories) {
        ImmutableSet.Builder<FunctionLibrary> librarySet = ImmutableSet.builder();
        // The core library is always included.
        librarySet.add(CoreFunctions.LIBRARY);
        for (FunctionRepository repository : repositories) {
            librarySet.addAll(repository.getLibraries());
        }
        ImmutableMap.Builder<String, FunctionLibrary> builder = ImmutableMap.builder();
        for (FunctionLibrary library : librarySet.build()) {
            builder.put(library.getNamespace(), library);
        }
        return new FunctionRepository(builder.build());
    }

    private final ImmutableMap<String, FunctionLibrary> libraryMap;
    private final transient Map<String, Function> functionCache = new HashMap<String, Function>();

    private FunctionRepository(ImmutableMap<String, FunctionLibrary> libraryMap) {
        this.libraryMap = libraryMap;
    }

    public void reload() {
        invalidateFunctionCache();
        for (FunctionLibrary library : getLibraries()) {
            if (library == CoreFunctions.LIBRARY) continue;
            library.reload();
        }
    }

    public void invalidateFunctionCache() {
        functionCache.clear();
    }

    public Function getFunction(String identifier) {
        if (functionCache.containsKey(identifier)) {
            return functionCache.get(identifier);
        } else {
            String[] functionParts = identifier.split("/");
            checkArgument(functionParts.length == 2, "The function identifier should be in the form 'namespace/function'.");
            String namespace = functionParts[0];
            String functionName = functionParts[1];
            FunctionLibrary library = libraryMap.get(namespace);
            checkArgument(library != null, "Could not find function %s: unknown namespace.", identifier);
            assert library != null; // To avoid a compiler warning.
            checkArgument(library.hasFunction(functionName), "Could not find function %s: unknown function.", identifier);
            Function function = library.getFunction(functionName);
            functionCache.put(identifier, function);
            return function;
        }
    }

    public boolean hasFunction(String identifier) {
        try {
            return getFunction(identifier) != null;
        } catch (Exception e) {
            return false;
        }
    }

    public Node nodeForFunction(String identifier) {
        Function function = getFunction(identifier);
        Node n = Node.ROOT.withFunction(identifier);
        for (Function.Argument arg : function.getArguments()) {
            n = n.withInputAdded(Port.portForType(arg.getName(), arg.getType()));
        }
        return n;
    }

    public Collection<FunctionLibrary> getLibraries() {
        return libraryMap.values();
    }

    public boolean hasLibrary(String namespace) {
        return libraryMap.containsKey(namespace);
    }

    public FunctionLibrary getLibrary(String namespace) {
        checkNotNull(namespace);
        checkArgument(libraryMap.containsKey(namespace), "Could not find library %s: unknown namespace.", namespace);
        return libraryMap.get(namespace);
    }

    public FunctionRepository withLibraryAdded(FunctionLibrary newLibrary) {
        List<FunctionLibrary> newLibraries = new ArrayList<FunctionLibrary>();

        Collection<FunctionLibrary> libraries = getLibraries();
        if (libraries.contains(newLibrary)) {
            for (FunctionLibrary library : libraries) {
                if (library.equals(newLibrary))
                    newLibraries.add(newLibrary);
                else
                    newLibraries.add(library);
            }
        } else {
            newLibraries.addAll(libraries);
            newLibraries.add(newLibrary);
        }

        FunctionLibrary[] fl = newLibraries.toArray(new FunctionLibrary[newLibraries.size()]);
        return FunctionRepository.of(fl);
    }

    public FunctionRepository withLibraryRemoved(FunctionLibrary library) {
        checkNotNull(library);
        checkArgument(hasLibrary(library.getNamespace()), "Could not find library %s: unknown namespace.", library.getNamespace());
        List<FunctionLibrary> newLibraries = new ArrayList<FunctionLibrary>();
        newLibraries.addAll(getLibraries());
        newLibraries.remove(library);
        FunctionLibrary[] fl = newLibraries.toArray(new FunctionLibrary[newLibraries.size()]);
        return FunctionRepository.of(fl);
    }

    //// Object overrides ////

    @Override
    public int hashCode() {
        return Objects.hashCode(libraryMap);
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof FunctionRepository)) return false;
        final FunctionRepository other = (FunctionRepository) o;
        return Objects.equal(libraryMap, other.libraryMap);
    }

    @Override
    public String toString() {
        return String.format("<FunctionRepository %s>", Joiner.on(", ").join(libraryMap.values()));
    }

}
TOP

Related Classes of nodebox.function.FunctionRepository

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.