uk.ac.open.kmi.iserve.discovery.disco.impl.OperationDataflowMatcher.java Source code

Java tutorial

Introduction

Here is the source code for uk.ac.open.kmi.iserve.discovery.disco.impl.OperationDataflowMatcher.java

Source

/*
 * Copyright (c) 2013. Knowledge Media Institute - The Open University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package uk.ac.open.kmi.iserve.discovery.disco.impl;

import com.google.common.base.Functions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.common.collect.Table;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import uk.ac.open.kmi.iserve.discovery.api.ConceptMatcher;
import uk.ac.open.kmi.iserve.discovery.api.DataflowMatcher;
import uk.ac.open.kmi.iserve.discovery.api.MatchResult;
import uk.ac.open.kmi.iserve.discovery.api.MatchType;
import uk.ac.open.kmi.iserve.discovery.api.impl.AbstractMatcher;
import uk.ac.open.kmi.iserve.discovery.api.impl.EnumMatchTypes;
import uk.ac.open.kmi.iserve.discovery.disco.LogicConceptMatchType;
import uk.ac.open.kmi.iserve.discovery.util.MatchResultComparators;
import uk.ac.open.kmi.iserve.sal.exception.SalException;
import uk.ac.open.kmi.iserve.sal.manager.ServiceManager;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import static uk.ac.open.kmi.iserve.discovery.disco.MatchResultsMerger.INTERSECTION;

/**
 * OperationDataflowMatcher implementation of DataflowMatching for Operations
 *
 * @author <a href="mailto:carlos.pedrinaci@open.ac.uk">Carlos Pedrinaci</a> (KMi - The Open University)
 * @since 27/09/2013
 */
public class OperationDataflowMatcher extends AbstractMatcher implements DataflowMatcher {

    private static final Logger log = LoggerFactory.getLogger(OperationDataflowMatcher.class);

    private final ServiceManager serviceManager;
    private final ConceptMatcher conceptMatcher;

    @Inject
    protected OperationDataflowMatcher(ServiceManager serviceManager, ConceptMatcher conceptMatcher)
            throws SalException {

        super(EnumMatchTypes.of(LogicConceptMatchType.class));

        this.serviceManager = serviceManager;
        this.conceptMatcher = conceptMatcher;
    }

    /**
     * Obtains a brief textual description of the particular Matcher to be presented to the user.
     *
     * @return the textual description
     */
    @Override
    public String getMatcherDescription() {
        return OperationDataflowMatcher.class.getCanonicalName();
    }

    /**
     * Obtains the particular version of the matcher being used.
     *
     * @return the version
     */
    @Override
    public String getMatcherVersion() {
        return "v1.0-SNAPSHOT"; // TODO: auto configure
    }

    /**
     * Perform a match between two URIs (from {@code origin} to {@code destination})
     * and returns the result.
     *
     * @param origin      URI of the element to match
     * @param destination URI of the element to match against
     * @return {@link uk.ac.open.kmi.iserve.discovery.api.MatchResult} with the result of the matching.
     */
    @Override
    public MatchResult match(URI origin, URI destination) {

        Set<URI> originOutputs = this.serviceManager.listOutputs(origin);
        Set<URI> destinationInputs = this.serviceManager.listInputs(destination);

        // Obtain all combinations of matches
        Table<URI, URI, MatchResult> matches = this.conceptMatcher.match(originOutputs, destinationInputs);
        // Collect the best match results for each of the destination's inputs
        // We should try and maximise the fulfillment of destination's inputs rather than be guided by the origin outputs
        ImmutableSet.Builder<MatchResult> builder = ImmutableSet.builder();

        for (Map.Entry<URI, Map<URI, MatchResult>> entry : matches.columnMap().entrySet()) {
            Map<URI, MatchResult> matchesMap = entry.getValue();
            Ordering<URI> valueComparator = Ordering.from(MatchResultComparators.BY_TYPE)
                    .onResultOf(Functions.forMap(matchesMap)) // Order by value
                    .compound(Ordering.natural()); // Order by URI eventually

            URI bestMatchUri = valueComparator.max(matchesMap.keySet());
            log.info("The best match for {} is {}, with a Match Result of {}", entry.getKey(), bestMatchUri,
                    matchesMap.get(bestMatchUri).getMatchType());

            builder.add(matchesMap.get(bestMatchUri));
        }

        MatchResult result = INTERSECTION.apply(builder.build());
        log.info("Combined match result - {}", result);
        return result;
    }

    /**
     * Obtain all the matching resources with the URI of {@code origin} within the range of MatchTypes provided, both inclusive.
     *
     * @param origin  URI to match
     * @param minType the minimum MatchType we want to obtain
     * @param maxType the maximum MatchType we want to obtain
     * @return a Map containing indexed by the URI of the matching resource and containing the particular {@code MatchResult}. If no
     *         result is found the Map should be empty not null.
     */
    @Override
    public Map<URI, MatchResult> listMatchesWithinRange(URI origin, MatchType minType, MatchType maxType) {

        // Input validation
        if (origin == null)
            return ImmutableMap.of();

        if (minType == null)
            minType = this.getMatchTypesSupported().getLowest();

        if (maxType == null)
            maxType = this.getMatchTypesSupported().getHighest();

        // TODO: Implement
        return ImmutableMap.of();

    }
}