edu.wpi.checksims.algorithm.smithwaterman.SmithWaterman.java Source code

Java tutorial

Introduction

Here is the source code for edu.wpi.checksims.algorithm.smithwaterman.SmithWaterman.java

Source

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * See LICENSE.txt included in this distribution for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at LICENSE.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 * Copyright (c) 2014-2015 Matthew Heon and Dolan Murvihill
 */

package edu.wpi.checksims.algorithm.smithwaterman;

import edu.wpi.checksims.algorithm.AlgorithmResults;
import edu.wpi.checksims.algorithm.InternalAlgorithmError;
import edu.wpi.checksims.algorithm.SimilarityDetector;
import edu.wpi.checksims.submission.Submission;
import edu.wpi.checksims.token.TokenList;
import edu.wpi.checksims.token.TokenType;
import edu.wpi.checksims.token.TokenTypeMismatchException;
import org.apache.commons.lang3.tuple.Pair;

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

/**
 * Implementation of the Smith-Waterman algorithm.
 */
public class SmithWaterman implements SimilarityDetector {
    private static SmithWaterman instance;

    private SmithWaterman() {
    }

    /**
     * @return Singleton instance of the Smith-Waterman algorithm
     */
    public static SmithWaterman getInstance() {
        if (instance == null) {
            instance = new SmithWaterman();
        }

        return instance;
    }

    /**
     * @return Name of this implementation
     */
    @Override
    public String getName() {
        return "smithwaterman";
    }

    /**
     * @return Default token type to be used for this similarity detector
     */
    @Override
    public TokenType getDefaultTokenType() {
        return TokenType.WHITESPACE;
    }

    /**
     * Apply the Smith-Waterman algorithm to determine the similarity between two submissions.
     *
     * Token list types of A and B must match
     *
     * @param a First submission to apply to
     * @param b Second submission to apply to
     * @return Similarity results of comparing submissions A and B
     * @throws TokenTypeMismatchException Thrown on comparing submissions with mismatched token types
     * @throws InternalAlgorithmError Thrown on internal error
     */
    @Override
    public AlgorithmResults detectSimilarity(Submission a, Submission b)
            throws TokenTypeMismatchException, InternalAlgorithmError {
        checkNotNull(a);
        checkNotNull(b);

        // Test for token type mismatch
        if (!a.getTokenType().equals(b.getTokenType())) {
            throw new TokenTypeMismatchException("Token list type mismatch: submission " + a.getName()
                    + " has type " + a.getTokenType().toString() + ", while submission " + b.getName()
                    + " has type " + b.getTokenType().toString());
        }

        // Handle a 0-token submission (no similarity)
        if (a.getNumTokens() == 0 || b.getNumTokens() == 0) {
            return new AlgorithmResults(a, b, a.getContentAsTokens(), b.getContentAsTokens());
        } else if (a.equals(b)) {
            // Handle identical submissions
            TokenList aInval = TokenList.cloneTokenList(a.getContentAsTokens());
            aInval.stream().forEach((token) -> token.setValid(false));
            return new AlgorithmResults(a, b, aInval, aInval);
        }

        // Alright, easy cases taken care of. Generate an instance to perform the actual algorithm
        SmithWatermanAlgorithm algorithm = new SmithWatermanAlgorithm(a.getContentAsTokens(),
                b.getContentAsTokens());

        Pair<TokenList, TokenList> endLists = algorithm.computeSmithWatermanAlignmentExhaustive();

        return new AlgorithmResults(a, b, endLists.getLeft(), endLists.getRight());
    }

    @Override
    public String toString() {
        return "Singleton instance of Smith-Waterman Algorithm";
    }
}