pax_global_header00006660000000000000000000000064117741253130014516gustar00rootroot0000000000000052 comment=84aa5af7732f972656522b33f5dd89e05ea99aaf libsequence-java-1.0.2/000077500000000000000000000000001177412531300147345ustar00rootroot00000000000000libsequence-java-1.0.2/LICENSE.txt000066400000000000000000000043441177412531300165640ustar00rootroot00000000000000Sequence Library License This license applies to all portions of the Sequence library, which are not externally-maintained libraries (e.g. junit or jsch). ==================================================================== Copyright (c) 2000-2008 SyntEvo GmbH, Ainring, GERMANY. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by SyntEvo GmbH, Ainring, GERMANY." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The hosted project names must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact info@syntevo.com. 5. Neither the name of SyntEvo GmbH nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SyntEvo GmbH OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ==================================================================== libsequence-java-1.0.2/build.defaults.gradle000066400000000000000000000010461177412531300210220ustar00rootroot00000000000000project.ext.setProperty('buildPluginRepositoryURL', 'http://maven.tmatesoft.com:8080/content/repositories/releases/') if (!project.hasProperty('mavenProxyRepository.url')) { setPropertyDefaultValue('mavenCentralRepository.url', 'http://repo1.maven.org/maven2/') setPropertyDefaultValue('mavenTMateSoftRepository.url', 'http://maven.tmatesoft.com/content/repositories/snapshots') } def setPropertyDefaultValue(String name, String value) { if (!project.hasProperty(name)) { project.ext.setProperty(name, value) } }libsequence-java-1.0.2/build.gradle000066400000000000000000000024731177412531300172210ustar00rootroot00000000000000group = 'de.regnis.q.sequence' version = '1.0.2' project.ext { target = '1.4' release = true } apply from: 'build.pom.gradle' buildscript { apply from: 'build.defaults.gradle' configurations.all { resolutionStrategy { cacheChangingModulesFor 0, 'seconds' cacheDynamicVersionsFor 0, 'seconds' } } repositories { maven { url project.ext.buildPluginRepositoryURL } } dependencies { classpath 'org.tmatesoft.build:build:0.9.9' } } task wrapper(type: Wrapper) {} configure(rootProject) { apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'signing' apply plugin: 'build' targetCompatibility = target sourceCompatibility = target dependencies { testCompile 'junit:junit:3.8.2' } task javadocJar(type: Jar, dependsOn: javadoc) { description="Builds Javadoc Jar" from "$docsDir/javadoc" classifier = 'javadoc' } task sourcesJar(type: Jar) { description = 'Builds Java Sources Jar' from sourceSets.main.java.srcDirs classifier = 'sources' } jar { metaInf { from rootProject.file('LICENSE.txt') } } artifacts { maven jar, sourcesJar, javadocJar } }libsequence-java-1.0.2/build.pom.gradle000066400000000000000000000010161177412531300200030ustar00rootroot00000000000000project.ext { packaging = 'jar' pomName = 'Sequence Library' pomUrl = 'http://svn.svnkit.com/repos/3rdparty/de.regnigs.q.sequence' pomDescription = 'Textual Diff and Merge Library' licenses = [['name': 'Sequence Library License', 'url' : 'http://www.svnkit.com/SEQUENCE-LICENSE.txt']] scm = ['url': 'http://svn.svnkit.com/repos/3rdparty/de.regnigs.q.sequence', 'connection': 'scm:svn:http://svn.svnkit.com/repos/3rdparty/de.regnigs.q.sequence'] developers = [['id': 'syntevo', 'name' : 'SyntEvo GmbH']] }libsequence-java-1.0.2/gradle/000077500000000000000000000000001177412531300161725ustar00rootroot00000000000000libsequence-java-1.0.2/gradle/wrapper/000077500000000000000000000000001177412531300176525ustar00rootroot00000000000000libsequence-java-1.0.2/gradle/wrapper/gradle-wrapper.properties000066400000000000000000000003531177412531300247050ustar00rootroot00000000000000#Fri Apr 22 16:45:48 CEST 2011 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=http\://services.gradle.org/distributions/gradle-1.0-rc-3-bin.zip libsequence-java-1.0.2/gradlew000077500000000000000000000134221177412531300163110ustar00rootroot00000000000000#!/bin/bash ############################################################################## ## ## ## Gradle wrapper script for UN*X ## ## ## ############################################################################## # Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. # GRADLE_OPTS="$GRADLE_OPTS -Xmx512m" # JAVA_OPTS="$JAVA_OPTS -Xmx512m" GRADLE_APP_NAME=Gradle # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set JAVA_HOME if it's not already set. if [ -z "$JAVA_HOME" ] ; then if $darwin ; then [ -z "$JAVA_HOME" -a -d "/Library/Java/Home" ] && export JAVA_HOME="/Library/Java/Home" [ -z "$JAVA_HOME" -a -d "/System/Library/Frameworks/JavaVM.framework/Home" ] && export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Home" else javaExecutable="`which javac`" [ -z "$javaExecutable" -o "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ] && die "JAVA_HOME not set and cannot find javac to deduce location, please set JAVA_HOME." # readlink(1) is not available as standard on Solaris 10. readLink=`which readlink` [ `expr "$readLink" : '\([^ ]*\)'` = "no" ] && die "JAVA_HOME not set and readlink not available, please set JAVA_HOME." javaExecutable="`readlink -f \"$javaExecutable\"`" javaHome="`dirname \"$javaExecutable\"`" javaHome=`expr "$javaHome" : '\(.*\)/bin'` export JAVA_HOME="$javaHome" fi fi # For Cygwin, ensure paths are in UNIX format before anything is touched. if $cygwin ; then [ -n "$JAVACMD" ] && JAVACMD=`cygpath --unix "$JAVACMD"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain CLASSPATH=`dirname "$0"`/gradle/wrapper/gradle-wrapper.jar WRAPPER_PROPERTIES=`dirname "$0"`/gradle/wrapper/gradle-wrapper.properties # Determine the Java command to use to start the JVM. if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD="java" fi fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi if [ -z "$JAVA_HOME" ] ; then warn "JAVA_HOME environment variable is not set" fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add GRADLE_APP_NAME to the JAVA_OPTS as -Xdock:name if $darwin; then JAVA_OPTS="$JAVA_OPTS -Xdock:name=$GRADLE_APP_NAME" # we may also want to set -Xdock:image fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then JAVA_HOME=`cygpath --path --mixed "$JAVA_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi GRADLE_APP_BASE_NAME=`basename "$0"` exec "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \ -classpath "$CLASSPATH" \ -Dorg.gradle.appname="$GRADLE_APP_BASE_NAME" \ -Dorg.gradle.wrapper.properties="$WRAPPER_PROPERTIES" \ $STARTER_MAIN_CLASS \ "$@" libsequence-java-1.0.2/gradlew.bat000077500000000000000000000046701177412531300170630ustar00rootroot00000000000000@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem ## @rem Gradle startup script for Windows ## @rem ## @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Uncomment those lines to set JVM options. GRADLE_OPTS and JAVA_OPTS can be used together. @rem set GRADLE_OPTS=%GRADLE_OPTS% -Xmx512m @rem set JAVA_OPTS=%JAVA_OPTS% -Xmx512m set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=.\ @rem Find java.exe set JAVA_EXE=java.exe if not defined JAVA_HOME goto init set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. echo. goto end :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set STARTER_MAIN_CLASS=org.gradle.wrapper.GradleWrapperMain set CLASSPATH=%DIRNAME%\gradle\wrapper\gradle-wrapper.jar set WRAPPER_PROPERTIES=%DIRNAME%\gradle\wrapper\gradle-wrapper.properties set GRADLE_OPTS=%JAVA_OPTS% %GRADLE_OPTS% -Dorg.gradle.wrapper.properties="%WRAPPER_PROPERTIES%" @rem Execute Gradle "%JAVA_EXE%" %GRADLE_OPTS% -classpath "%CLASSPATH%" %STARTER_MAIN_CLASS% %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd if not "%OS%"=="Windows_NT" echo 1 > nul | choice /n /c:1 rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit "%ERRORLEVEL%" exit /b "%ERRORLEVEL%" :mainEnd if "%OS%"=="Windows_NT" endlocal :omegalibsequence-java-1.0.2/settings.gradle000066400000000000000000000000451177412531300177530ustar00rootroot00000000000000rootProject.name = 'sequence-library'libsequence-java-1.0.2/src/000077500000000000000000000000001177412531300155235ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/000077500000000000000000000000001177412531300164475ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/000077500000000000000000000000001177412531300173705ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/000077500000000000000000000000001177412531300177605ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/000077500000000000000000000000001177412531300212475ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/000077500000000000000000000000001177412531300215075ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/000077500000000000000000000000001177412531300233175ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceCommonBlockFactory.java000066400000000000000000000012571177412531300315340ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; /** * @author Marc Strapetz */ public interface QSequenceCommonBlockFactory { Object createCommonBlock(int leftFrom, int leftTo, int rightFrom, int rightTo); Object createDistinctBlock(int leftFrom, int leftTo, int rightFrom, int rightTo); }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceCommonBlocks.java000066400000000000000000000044201177412531300303620ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceCommonBlocks { // Accessing ============================================================== public static List createBlocks(boolean[] leftCommonPoints, boolean[] rightCommonPoints, QSequenceCommonBlockFactory factory) { final List blocks = new ArrayList(); int leftIndex = 0; int rightIndex = 0; while (leftIndex < leftCommonPoints.length || rightIndex < rightCommonPoints.length) { int leftStart = leftIndex; int rightStart = rightIndex; while (leftIndex < leftCommonPoints.length && rightIndex < rightCommonPoints.length && leftCommonPoints[leftIndex] && rightCommonPoints[rightIndex]) { leftIndex++; rightIndex++; } if (leftIndex > leftStart && rightIndex > rightStart) { final Object block = factory.createCommonBlock(leftStart, leftIndex - 1, rightStart, rightIndex - 1); if (block != null) { blocks.add(block); } } leftStart = leftIndex; rightStart = rightIndex; while ((leftIndex < leftCommonPoints.length && !leftCommonPoints[leftIndex]) || (rightIndex < rightCommonPoints.length && !rightCommonPoints[rightIndex])) { if (leftIndex < leftCommonPoints.length && !leftCommonPoints[leftIndex]) { leftIndex++; } if (rightIndex < rightCommonPoints.length && !rightCommonPoints[rightIndex]) { rightIndex++; } } if (leftIndex > leftStart || rightIndex > rightStart) { final Object block = factory.createDistinctBlock(leftStart, leftIndex - 1, rightStart, rightIndex - 1); if (block != null) { blocks.add(block); } } QSequenceAssert.assertTrue((leftIndex >= leftCommonPoints.length && rightIndex >= rightCommonPoints.length) || (leftCommonPoints[leftIndex] && rightCommonPoints[rightIndex])); } return blocks; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceDifference.java000066400000000000000000000057421177412531300300360ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceDifference implements QSequenceSnakeRegister, QSequenceCommonBlockFactory { // Fields ================================================================= private final QSequenceMedia media; private final QSequenceMediaIndexTransformer indexTransformer; private final boolean[] leftCommonPoints; private final boolean[] rightCommonPoints; private final int maximumSearchDepth; // Setup ================================================================== public QSequenceDifference(QSequenceMedia media, QSequenceMediaIndexTransformer indexTransformer) { this(media, indexTransformer, Integer.MAX_VALUE); } public QSequenceDifference(QSequenceMedia media, QSequenceMediaIndexTransformer indexTransformer, int maximumSearchDepth) { QSequenceAssert.assertNotNull(media); QSequenceAssert.assertNotNull(indexTransformer); this.media = media; this.indexTransformer = indexTransformer; this.leftCommonPoints = new boolean[indexTransformer.getMediaLeftLength()]; this.rightCommonPoints = new boolean[indexTransformer.getMediaRightLength()]; this.maximumSearchDepth = maximumSearchDepth; } // Implemented ============================================================ public void registerSnake(int leftFrom, int leftTo, int rightFrom, int rightTo) throws QSequenceCancelledException { for (int leftIndex = leftFrom; leftIndex <= leftTo; leftIndex++) { QSequenceAssert.assertTrue(!leftCommonPoints[indexTransformer.getMediaLeftIndex(leftIndex)]); leftCommonPoints[indexTransformer.getMediaLeftIndex(leftIndex)] = true; } for (int rightIndex = rightFrom; rightIndex <= rightTo; rightIndex++) { QSequenceAssert.assertTrue(!rightCommonPoints[indexTransformer.getMediaRightIndex(rightIndex)]); rightCommonPoints[indexTransformer.getMediaRightIndex(rightIndex)] = true; } } public Object createCommonBlock(int leftFrom, int leftTo, int rightFrom, int rightTo) { return null; } public Object createDistinctBlock(int leftFrom, int leftTo, int rightFrom, int rightTo) { return new QSequenceDifferenceBlock(leftFrom, leftTo, rightFrom, rightTo); } // Accessing ============================================================== public List getBlocks() throws QSequenceException { final QSequenceAlgorithm algorithm = new QSequenceAlgorithm(media, this, maximumSearchDepth); algorithm.produceSnakesInOrder(); return QSequenceCommonBlocks.createBlocks(leftCommonPoints, rightCommonPoints, this); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceDifferenceBlock.java000066400000000000000000000037271177412531300310120ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceBlock { // Fields ================================================================= private int leftFrom; private int leftTo; private int rightFrom; private int rightTo; // Setup ================================================================== public QSequenceDifferenceBlock(int leftFrom, int leftTo, int rightFrom, int rightTo) { QSequenceAssert.assertTrue(leftFrom <= leftTo || rightFrom <= rightTo); this.leftFrom = leftFrom; this.leftTo = leftTo; this.rightFrom = rightFrom; this.rightTo = rightTo; } // Accessing ============================================================== public int getLeftFrom() { return leftFrom; } public int getLeftTo() { return leftTo; } public int getLeftSize() { return leftTo - leftFrom + 1; } public int getRightFrom() { return rightFrom; } public int getRightTo() { return rightTo; } public int getRightSize() { return rightTo - rightFrom + 1; } // Package ================================================================ void setLeftFrom(int leftFrom) { this.leftFrom = leftFrom; } void setLeftTo(int leftTo) { this.leftTo = leftTo; } void setRightFrom(int rightFrom) { this.rightFrom = rightFrom; } void setRightTo(int rightTo) { this.rightTo = rightTo; } // Implemented ============================================================ public String toString() { return "[" + leftFrom + "/" + leftTo + "/" + rightFrom + "/" + rightTo + "]"; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceDifferenceBlockShifter.java000066400000000000000000000132601177412531300323300ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceBlockShifter { // Static ================================================================= public static void joinBlocks(List blocks) { QSequenceDifferenceBlock lastBlock = null; for (int index = 0; index < blocks.size();) { final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(index); if (lastBlock == null) { index++; lastBlock = block; continue; } QSequenceAssert.assertTrue(lastBlock.getLeftTo() < block.getLeftFrom()); QSequenceAssert.assertTrue(lastBlock.getRightTo() < block.getRightFrom()); if (lastBlock.getLeftTo() + 1 != block.getLeftFrom()) { QSequenceAssert.assertTrue(lastBlock.getRightTo() != block.getRightFrom() + 1); lastBlock = block; index++; continue; } if (lastBlock.getRightTo() + 1 != block.getRightFrom()) { QSequenceAssert.assertTrue(lastBlock.getLeftTo() != block.getLeftFrom() + 1); lastBlock = block; index++; continue; } lastBlock.setLeftTo(block.getLeftTo()); lastBlock.setRightTo(block.getRightTo()); blocks.remove(index); continue; } } // Fields ================================================================= private final QSequenceMedia media; private final QSequenceMediaComparer comparer; // Setup ================================================================== public QSequenceDifferenceBlockShifter(QSequenceMedia media, QSequenceMediaComparer comparer) { QSequenceAssert.assertNotNull(media); QSequenceAssert.assertNotNull(comparer); this.media = media; this.comparer = comparer; } // Accessing ============================================================== public void shiftBlocks(List blocks) throws QSequenceException { if (blocks.isEmpty()) { return; } joinBlocks(blocks); for (int index = 0; index < blocks.size();) { if (tryShiftUp(blocks, index, true)) { continue; } index++; } for (int index = 0; index < blocks.size();) { if (tryShiftDown(blocks, index)) { continue; } index++; } } public boolean tryShiftUp(List blocks, int blockIndex, boolean requireMerge) throws QSequenceException { if (blockIndex == 0) { return false; } final QSequenceDifferenceBlock prevBlock = (QSequenceDifferenceBlock)blocks.get(blockIndex - 1); final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(blockIndex); final int prevLeftTo = prevBlock.getLeftTo(); final int prevRightTo = prevBlock.getRightTo(); int leftFrom = block.getLeftFrom(); int leftTo = block.getLeftTo(); int rightFrom = block.getRightFrom(); int rightTo = block.getRightTo(); QSequenceAssert.assertTrue(leftFrom > prevLeftTo); QSequenceAssert.assertTrue(rightFrom > prevRightTo); QSequenceAssert.assertTrue(leftFrom <= leftTo || rightFrom <= rightTo); if (leftFrom - prevLeftTo != rightFrom - prevRightTo) { return false; } while (leftFrom > prevLeftTo + 1) { if (leftFrom <= leftTo && !comparer.equalsLeft(leftFrom - 1, leftTo)) { break; } if (rightFrom <= rightTo && !comparer.equalsRight(rightFrom - 1, rightTo)) { break; } leftFrom--; leftTo--; rightFrom--; rightTo--; } if (leftFrom > prevLeftTo + 1) { if (requireMerge) { return false; } block.setLeftFrom(leftFrom); block.setLeftTo(leftTo); block.setRightFrom(rightFrom); block.setRightTo(rightTo); } else { prevBlock.setLeftTo(prevBlock.getLeftTo() + (leftTo - leftFrom + 1)); prevBlock.setRightTo(prevBlock.getRightTo() + (rightTo - rightFrom + 1)); blocks.remove(blockIndex); } return true; } public boolean tryShiftDown(List blocks, int blockIndex) throws QSequenceException { final QSequenceDifferenceBlock nextBlock = blockIndex < blocks.size() - 1 ? (QSequenceDifferenceBlock)blocks.get(blockIndex + 1) : null; final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(blockIndex); final int nextLeftFrom = nextBlock != null ? nextBlock.getLeftFrom() : media.getLeftLength(); final int nextRightFrom = nextBlock != null ? nextBlock.getRightFrom() : media.getRightLength(); int leftFrom = block.getLeftFrom(); int leftTo = block.getLeftTo(); int rightFrom = block.getRightFrom(); int rightTo = block.getRightTo(); QSequenceAssert.assertTrue(leftTo < nextLeftFrom); QSequenceAssert.assertTrue(rightTo < nextRightFrom); QSequenceAssert.assertTrue(leftFrom <= leftTo || rightFrom <= rightTo); while (leftTo < nextLeftFrom - 1 && rightTo < nextRightFrom - 1) { if (leftFrom <= leftTo && !comparer.equalsLeft(leftFrom, leftTo + 1)) { break; } if (rightFrom <= rightTo && !comparer.equalsRight(rightFrom, rightTo + 1)) { break; } leftFrom++; leftTo++; rightFrom++; rightTo++; } if (nextBlock != null && leftTo == nextLeftFrom - 1 && rightTo == nextRightFrom - 1) { nextBlock.setLeftFrom(nextBlock.getLeftFrom() - (leftTo - leftFrom + 1)); nextBlock.setRightFrom(nextBlock.getRightFrom() - (rightTo - rightFrom + 1)); blocks.remove(blockIndex); return true; } block.setLeftFrom(leftFrom); block.setLeftTo(leftTo); block.setRightFrom(rightFrom); block.setRightTo(rightTo); return false; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceDifferenceBlockUtils.java000066400000000000000000000021161177412531300320220ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceBlockUtils { // Accessing ============================================================== public static List createCopy(List blocks) { final List copy = new ArrayList(); for (Iterator it = blocks.iterator(); it.hasNext();) { final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)it.next(); copy.add(createCopy(block)); } return copy; } public static QSequenceDifferenceBlock createCopy(QSequenceDifferenceBlock block) { return new QSequenceDifferenceBlock(block.getLeftFrom(), block.getLeftTo(), block.getRightFrom(), block.getRightTo()); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceSimpleLCS.java000066400000000000000000000026661177412531300276010ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceSimpleLCS implements QSequenceSnakeRegister { // Fields ================================================================= private final QSequenceMedia media; private final List commands = new ArrayList(); // Setup ================================================================== public QSequenceSimpleLCS(QSequenceMedia media) { this.media = media; } // Implemented ============================================================ public void registerSnake(int leftFrom, int leftTo, int rightFrom, int rightTo) { commands.add(new QSequenceSimpleLCSCommand(true, leftFrom, leftTo)); } // Accessing ============================================================== public List getCommands() throws QSequenceException { commands.clear(); final QSequenceAlgorithm algorithm = new QSequenceAlgorithm(media, this, Integer.MAX_VALUE); algorithm.produceSnakesInOrder(); return commands; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/QSequenceSimpleLCSCommand.java000066400000000000000000000020731177412531300310700ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; /** * @author Marc Strapetz */ public class QSequenceSimpleLCSCommand { // Fields ================================================================= private final boolean left; private final int from; private final int to; // Setup ================================================================== public QSequenceSimpleLCSCommand(boolean left, int from, int to) { this.left = left; this.from = from; this.to = to; } // Accessing ============================================================== public boolean isLeft() { return left; } public int getFrom() { return from; } public int getTo() { return to; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/000077500000000000000000000000001177412531300242475ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceAlgorithm.java000066400000000000000000000100321177412531300306460ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public class QSequenceAlgorithm { // Constants ============================================================== public static final boolean ASSERTIONS = true; // Fields ================================================================= private final QSequenceMedia mainMedia; private final QSequenceSnakeRegister snakeRegister; private final QSequenceMiddleSnakeFinder finder; // Setup ================================================================== public QSequenceAlgorithm(QSequenceMedia media, QSequenceSnakeRegister snakeRegister, int maximumSearchDepth) { QSequenceAssert.assertTrue(maximumSearchDepth >= 2); // Because for dee == 1, there is a special treatment in produceSnakesInOrder. this.mainMedia = media; this.snakeRegister = snakeRegister; this.finder = new QSequenceMiddleSnakeFinder(media.getLeftLength(), media.getRightLength(), maximumSearchDepth); } // Accessing ============================================================== public void produceSnakesInOrder() throws QSequenceException { final QSequenceRestrictedMedia media = new QSequenceRestrictedMedia(mainMedia); produceSnakesInOrder(media); } // Utils ================================================================== private void produceSnakesInOrder(QSequenceRestrictedMedia media) throws QSequenceException { final int leftLength = media.getLeftLength(); final int rightLength = media.getRightLength(); if (leftLength < 1 || rightLength < 1) { return; } final int dee = finder.determineMiddleSnake(media); if (dee <= 0) { registerSnake(media, 1, leftLength, 1, rightLength); return; } final int leftFrom = finder.getResult().getLeftFrom(); final int rightFrom = finder.getResult().getRightFrom(); final int leftTo = finder.getResult().getLeftTo(); final int rightTo = finder.getResult().getRightTo(); if (dee == 1) { if (rightLength == leftLength + 1) { registerSnake(media, 1, leftFrom, 1, rightFrom - 1); registerSnake(media, leftFrom + 1, leftTo, rightFrom + 1, rightTo); } else if (leftLength == rightLength + 1) { registerSnake(media, 1, leftFrom - 1, 1, rightFrom); registerSnake(media, leftFrom + 1, leftTo, rightFrom + 1, rightTo); } else { QSequenceAssert.assertTrue(false); } return; } final int leftMin = media.getLeftMin(); final int rightMin = media.getRightMin(); final int leftMax = media.getLeftMax(); final int rightMax = media.getRightMax(); try { media.restrictTo(leftMin, leftMin + leftFrom - 1, rightMin, rightMin + rightFrom - 1); produceSnakesInOrder(media); media.restrictTo(leftMin, leftMax, rightMin, rightMax); registerSnake(media, leftFrom + 1, leftTo, rightFrom + 1, rightTo); media.restrictTo(leftMin + leftTo - 1 + 1, leftMax, rightMin + rightTo - 1 + 1, rightMax); produceSnakesInOrder(media); } finally { media.restrictTo(leftMin, leftMax, rightMin, rightMax); } } private void registerSnake(QSequenceRestrictedMedia media, int leftFrom, int leftTo, int rightFrom, int rightTo) throws QSequenceException { QSequenceAssert.assertTrue(leftTo - leftFrom == rightTo - rightFrom); if (leftFrom > leftTo || rightFrom > rightTo) { return; } for (int index = 0; index < leftTo - leftFrom; index++) { QSequenceAssert.assertTrue(media.equals(leftFrom + index, rightFrom + index)); } leftFrom = media.getLeftMin() + leftFrom - 1; leftTo = media.getLeftMin() + leftTo - 1; rightFrom = media.getRightMin() + rightFrom - 1; rightTo = media.getRightMin() + rightTo - 1; snakeRegister.registerSnake(leftFrom - 1, leftTo - 1, rightFrom - 1, rightTo - 1); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceAssert.java000066400000000000000000000027631177412531300301750ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public final class QSequenceAssert { // Static ================================================================= public static void assertNotNull(Object obj) { assertTrue(obj != null, "Object must not be null!"); } public static void assertNotNull(Object obj, String text) { assertTrue(obj != null, "Object must not be null: " + text); } public static void assertEquals(int i1, int i2) { assertTrue(i1 == i2, i1 + " != " + i2); } public static void assertEquals(long l1, long l2) { assertTrue(l1 == l2, l1 + " != " + l2); } public static void assertTrue(boolean forceTrueCondition) { assertTrue(forceTrueCondition, ""); } public static void assertTrue(boolean forceTrueCondition, String text) { if (!forceTrueCondition) { error(text); } } public static void error(String text) { throw new InternalError(text); } public static void fatal(String text) { throw new InternalError(text); } // Setup ================================================================== private QSequenceAssert() { } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceCancelledException.java000066400000000000000000000012371177412531300324600ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public class QSequenceCancelledException extends QSequenceException { // Setup ================================================================== public QSequenceCancelledException() { } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceCanceller.java000066400000000000000000000011001177412531300306040ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public interface QSequenceCanceller { void checkCancelled() throws QSequenceCancelledException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceDeePathBackwardExtender.java000066400000000000000000000036141177412531300334000ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ final class QSequenceDeePathBackwardExtender extends QSequenceDeePathExtender { // Fields ================================================================= private int delta; private int mediaLeftLength; private int mediaRightLength; // Setup ================================================================== public QSequenceDeePathBackwardExtender(int maximumMediaLeftLength, int maximumMediaRightLength) { super(new QSequenceDeePathExtenderArray(maximumMediaLeftLength + maximumMediaRightLength)); } // Accessing ============================================================== protected int getNextX(QSequenceDeePathExtenderArray xs, int diagonal, int dee) { if (diagonal - delta == dee || (diagonal - delta != -dee && xs.get(diagonal + 1) > xs.get(diagonal - 1))) { return xs.get(diagonal - 1); } return xs.get(diagonal + 1) - 1; } protected int getSnakeX(QSequenceMedia media, int x, int y) throws QSequenceException { for (; x > 0 && y > 0 && media.equals(x, y);) { x--; y--; } return x; } protected final void reset(QSequenceMedia media, QSequenceDeePathExtenderArray xs) { mediaLeftLength = media.getLeftLength(); mediaRightLength = media.getRightLength(); delta = mediaLeftLength - mediaRightLength; xs.setDelta(delta); xs.set(delta - 1, mediaLeftLength); } public int getProgress(int diagonal) { return mediaLeftLength - getLeft(diagonal) + mediaRightLength - getRight(diagonal); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceDeePathExtender.java000066400000000000000000000054211177412531300317370ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ abstract class QSequenceDeePathExtender { // Abstract =============================================================== protected abstract int getNextX(QSequenceDeePathExtenderArray xs, int diagonal, int dee); protected abstract int getSnakeX(QSequenceMedia media, int x, int y) throws QSequenceException; protected abstract void reset(QSequenceMedia media, QSequenceDeePathExtenderArray xs); public abstract int getProgress(int diagonal); // Fields ================================================================= private final QSequenceDeePathExtenderArray xs; private int snakeStartLeft; private int snakeStartRight; // Setup ================================================================== protected QSequenceDeePathExtender(QSequenceDeePathExtenderArray xs) { this.xs = xs; } // Accessing ============================================================== public final int getLeft(int diagonal) { return xs.get(diagonal); } public final int getRight(int diagonal) { return xs.get(diagonal) - diagonal; } public final int getSnakeStartLeft() { return snakeStartLeft; } public final int getSnakeStartRight() { return snakeStartRight; } public final void extendDeePath(QSequenceMedia media, int dee, int diagonal) throws QSequenceException { int x = getNextX(xs, diagonal, dee); int y = x - diagonal; snakeStartLeft = x; snakeStartRight = y; x = getSnakeX(media, x, y); y = x - diagonal; xs.set(diagonal, x); } public final void reset(QSequenceMedia media) { reset(media, xs); } public final void print(QSequenceMedia media, int fromDiagonal, int toDiagonal) { final StringBuffer[] lines = new StringBuffer[media.getRightLength() + 1]; for (int line = 0; line < lines.length; line++) { lines[line] = new StringBuffer(media.getLeftLength() + 1); lines[line].append('.'); for (int ch = 0; ch < media.getLeftLength(); ch++) { lines[line].append(line >= 1 && line <= media.getRightLength() ? '*' : '.'); } } for (int diagonal = fromDiagonal; diagonal <= toDiagonal; diagonal++) { final int left = getLeft(diagonal); final int right = getRight(diagonal); if (left < 0 || right < 0 || right >= lines.length || left >= lines[right].length()) { continue; } lines[right].setCharAt(left, String.valueOf(Math.abs(diagonal % 9)).charAt(0)); } } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceDeePathExtenderArray.java000066400000000000000000000031401177412531300327320ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ class QSequenceDeePathExtenderArray { // Fields ================================================================= private final int[] xs; private final int offset; private int delta; // Setup ================================================================== public QSequenceDeePathExtenderArray(int maximumMediaLeftRightLength) { this.offset = maximumMediaLeftRightLength; this.xs = new int[2 * maximumMediaLeftRightLength + 1]; } // Accessing ============================================================== public void set(int diagonal, int maxLeft) { if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(-offset + delta <= diagonal && diagonal <= offset + delta); } this.xs[offset - delta + diagonal] = maxLeft; } public int get(int diagonal) { if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(-offset + delta <= diagonal && diagonal <= offset + delta); } final int left = xs[offset - delta + diagonal]; if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(left != Integer.MAX_VALUE); } return left; } public void setDelta(int delta) { this.delta = delta; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceDeePathForwardExtender.java000066400000000000000000000030561177412531300332660ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ class QSequenceDeePathForwardExtender extends QSequenceDeePathExtender { // Setup ================================================================== public QSequenceDeePathForwardExtender(int maximumMediaLeftLength, int maximumMediaRightLength) { super(new QSequenceDeePathExtenderArray(maximumMediaLeftLength + maximumMediaRightLength)); } // Accessing ============================================================== protected int getNextX(QSequenceDeePathExtenderArray xs, int diagonal, int dee) { if (diagonal == -dee || (diagonal != dee && xs.get(diagonal - 1) < xs.get(diagonal + 1))) { return xs.get(diagonal + 1); } return xs.get(diagonal - 1) + 1; } protected int getSnakeX(QSequenceMedia media, int x, int y) throws QSequenceException { for (; x < media.getLeftLength() && y < media.getRightLength() && media.equals(x + 1, y + 1);) { x++; y++; } return x; } protected final void reset(QSequenceMedia media, QSequenceDeePathExtenderArray xs) { xs.set(1, 0); } public int getProgress(int diagonal) { return getLeft(diagonal) + getRight(diagonal); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceDummyCanceller.java000066400000000000000000000012261177412531300316310ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public class QSequenceDummyCanceller implements QSequenceCanceller { // Implemented ============================================================ public void checkCancelled() { } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceException.java000066400000000000000000000013061177412531300306620ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public class QSequenceException extends Exception { // Setup ================================================================== public QSequenceException() { } public QSequenceException(Throwable cause) { super(cause); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceMedia.java000066400000000000000000000011731177412531300277450ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public interface QSequenceMedia { int getLeftLength(); int getRightLength(); boolean equals(int leftIndex, int rightIndex) throws QSequenceException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceMiddleSnakeFinder.java000066400000000000000000000140611177412531300322360ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ class QSequenceMiddleSnakeFinder { // Fields ================================================================= private final QSequenceDeePathForwardExtender forwardDeePathExtender; private final QSequenceDeePathBackwardExtender backwardDeePathExtender; private final QSequenceMiddleSnakeFinderResult result; private final int maximumSearchDepth; // Setup ================================================================== public QSequenceMiddleSnakeFinder(int maximumMediaLeftLength, int maximumMediaRightLength, int maximumSearchDepth) { this.maximumSearchDepth = maximumSearchDepth; this.forwardDeePathExtender = new QSequenceDeePathForwardExtender(maximumMediaLeftLength, maximumMediaRightLength); this.backwardDeePathExtender = new QSequenceDeePathBackwardExtender(maximumMediaLeftLength, maximumMediaRightLength); this.result = new QSequenceMiddleSnakeFinderResult(); } // Accessing ============================================================== public QSequenceMiddleSnakeFinderResult getResult() { return result; } public int determineMiddleSnake(QSequenceMedia media) throws QSequenceException { result.reset(); forwardDeePathExtender.reset(media); backwardDeePathExtender.reset(media); final int delta = media.getLeftLength() - media.getRightLength(); final int deeMax = (int)Math.ceil(((double)media.getLeftLength() + (double)media.getRightLength()) / 2); for (int dee = 0; dee <= deeMax; dee++) { // Always run from dee to -dee to keep results more stable against slight changes like insertion/removal of a line: // Previous version was slightly more effective but *less stable* by starting the forward scan with those // diagonal which is nearer to the backward scan (i.e. at +dee for delta >= 0 and -dee for delta < 0). for (int diagonal = dee; diagonal >= -dee; diagonal -= 2) { forwardDeePathExtender.extendDeePath(media, dee, diagonal); if (checkForwardOverlapping(delta, diagonal, dee)) { if (isForwardAndBackwardOverlapping(diagonal)) { setMiddleSnake(result, forwardDeePathExtender, diagonal); return 2 * dee - 1; } } } for (int diagonal = dee; diagonal >= -dee; diagonal -= 2) { final int deltadDiagonal = diagonal + delta; backwardDeePathExtender.extendDeePath(media, dee, deltadDiagonal); if (checkBackwardOverlapping(delta, diagonal, dee)) { if (isForwardAndBackwardOverlapping(deltadDiagonal)) { setMiddleSnake(result, backwardDeePathExtender, deltadDiagonal); return 2 * dee; } } } if (dee < maximumSearchDepth) { continue; } return determineBestSnake(media, dee, delta); } QSequenceAssert.assertTrue(false); return 0; } // Utils ================================================================== private boolean isForwardAndBackwardOverlapping(int diagonal) { final int forwardLeft = forwardDeePathExtender.getLeft(diagonal); final int backwardLeft = backwardDeePathExtender.getLeft(diagonal); return forwardLeft >= backwardLeft; } private int determineBestSnake(QSequenceMedia media, int dee, final int delta) { final int bestForwardDiagonal = getBestForwardDiagonal(dee, delta); final int bestBackwardDiagonal = getBestBackwardDiagonal(dee, delta); if (forwardDeePathExtender.getProgress(bestForwardDiagonal) > backwardDeePathExtender.getProgress(bestBackwardDiagonal)) { final int left = forwardDeePathExtender.getLeft(bestForwardDiagonal); final int right = forwardDeePathExtender.getRight(bestForwardDiagonal); result.setMiddleSnake(left, right, left, right); return 2 * dee - 1; } final int left = backwardDeePathExtender.getLeft(bestBackwardDiagonal); final int right = backwardDeePathExtender.getRight(bestBackwardDiagonal); if (left < 0 || right < 0) { backwardDeePathExtender.print(media, -dee + delta, dee + delta); } result.setMiddleSnake(left, right, left, right); return 2 * dee; } private int getBestForwardDiagonal(int dee, int delta) { int bestDiagonal = 0; int bestProgress = 0; for (int diagonal = (delta >= 0 ? dee : -dee); (delta >= 0 ? diagonal >= -dee : diagonal <= dee); diagonal += (delta >= 0 ? -2 : 2)) { final int progress = forwardDeePathExtender.getProgress(diagonal); if (progress > bestProgress) { bestDiagonal = diagonal; bestProgress = progress; } } return bestDiagonal; } private int getBestBackwardDiagonal(int dee, int delta) { int bestDiagonal = delta; int bestProgress = 0; for (int diagonal = (delta >= 0 ? -dee : dee); (delta >= 0 ? diagonal <= dee : diagonal >= -dee); diagonal += (delta >= 0 ? 2 : -2)) { final int deltadDiagonal = diagonal + delta; final int progress = backwardDeePathExtender.getProgress(deltadDiagonal); if (progress > bestProgress) { bestDiagonal = deltadDiagonal; bestProgress = progress; } } return bestDiagonal; } public static void setMiddleSnake(QSequenceMiddleSnakeFinderResult result, QSequenceDeePathExtender extender, int diagonal) { result.setMiddleSnake(Math.min(extender.getLeft(diagonal), extender.getSnakeStartLeft()), Math.min(extender.getRight(diagonal), extender.getSnakeStartRight()), Math.max(extender.getLeft(diagonal), extender.getSnakeStartLeft()), Math.max(extender.getRight(diagonal), extender.getSnakeStartRight())); } private static boolean checkForwardOverlapping(final int delta, int diagonal, int dee) { return diagonal >= (delta - (dee - 1)) && diagonal <= (delta + (dee - 1)); } private static boolean checkBackwardOverlapping(final int delta, int diagonal, int dee) { return diagonal + delta >= -dee && diagonal + delta <= dee; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceMiddleSnakeFinderResult.java000066400000000000000000000026331177412531300334370ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ class QSequenceMiddleSnakeFinderResult { // Fields ================================================================= private int leftFrom; private int rightFrom; private int leftTo; private int rightTo; // Accessing ============================================================== public int getLeftFrom() { return leftFrom; } public int getRightFrom() { return rightFrom; } public int getLeftTo() { return leftTo; } public int getRightTo() { return rightTo; } public void reset() { leftFrom = 0; rightFrom = 0; leftTo = 0; rightTo = 0; } public void setMiddleSnake(int leftFrom, int rightFrom, int leftTo, int rightTo) { if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(0 <= leftFrom && leftFrom <= leftTo); QSequenceAssert.assertTrue(0 <= rightFrom && rightFrom <= rightTo); } this.leftFrom = leftFrom; this.rightFrom = rightFrom; this.leftTo = leftTo; this.rightTo = rightTo; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceRestrictedMedia.java000066400000000000000000000046551177412531300320060ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ class QSequenceRestrictedMedia implements QSequenceMedia { // Fields ================================================================= private final QSequenceMedia media; private int leftMin; private int rightMin; private int leftMax; private int rightMax; // Setup ================================================================== public QSequenceRestrictedMedia(QSequenceMedia media) { this.media = media; restrictTo(1, media.getLeftLength(), 1, media.getRightLength()); } // Accessing ============================================================== public void restrictTo(int leftMin, int leftMax, int rightMin, int rightMax) { if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(0 <= leftMin && leftMin <= leftMax + 1); QSequenceAssert.assertTrue(leftMax <= media.getLeftLength()); QSequenceAssert.assertTrue(0 <= rightMin && rightMin <= rightMax + 1); QSequenceAssert.assertTrue(rightMax <= media.getRightLength()); } this.leftMin = leftMin; this.leftMax = leftMax; this.rightMin = rightMin; this.rightMax = rightMax; } // Implemented ============================================================ public int getLeftLength() { return leftMax - leftMin + 1; } public int getRightLength() { return rightMax - rightMin + 1; } public boolean equals(int leftIndex, int rightIndex) throws QSequenceException { if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(1 <= leftIndex && leftIndex <= leftMax - leftMin + 1); } if (QSequenceAlgorithm.ASSERTIONS) { QSequenceAssert.assertTrue(1 <= rightIndex && rightIndex <= rightMax - rightMin + 1); } return media.equals(leftMin + leftIndex - 2, rightMin + rightIndex - 2); } // Accessing ============================================================== public int getLeftMin() { return leftMin; } public int getLeftMax() { return leftMax; } public int getRightMin() { return rightMin; } public int getRightMax() { return rightMax; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/core/QSequenceSnakeRegister.java000066400000000000000000000011671177412531300314770ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.core; /** * @author Marc Strapetz */ public interface QSequenceSnakeRegister { void registerSnake(int leftFrom, int leftTo, int rightFrom, int rightTo) throws QSequenceCancelledException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/000077500000000000000000000000001177412531300242465ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLine.java000066400000000000000000000042751177412531300276220ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ public final class QSequenceLine { // Fields ================================================================= private final long from; private final byte[] contentBytes; private final byte[] compareBytes; // Setup ================================================================== public QSequenceLine(long from, byte[] contentBytes, QSequenceLineSimplifier simplifier) { this.from = from; this.contentBytes = contentBytes; this.compareBytes = simplifier.simplify(contentBytes); } // Accessing ============================================================== public long getFrom() { return from; } public long getTo() { return from + contentBytes.length - 1; } public int getContentLength() { return contentBytes.length; } public byte[] getContentBytes() { return contentBytes; } /** * @deprecated */ public byte[] getBytes() { return getContentBytes(); } public int getCompareHash() { return new String(compareBytes).hashCode(); } // Implemented ============================================================ public boolean equals(Object obj) { // Must be because of caching media! Find something better! final byte[] otherBytes = ((QSequenceLine)obj).compareBytes; if (compareBytes.length != otherBytes.length) { return false; } for (int index = 0; index < compareBytes.length; index++) { if (compareBytes[index] != otherBytes[index]) { return false; } } return true; } public int hashCode() { int hashCode = 0; for (int index = 0; index < compareBytes.length; index++) { hashCode = 31 * hashCode + compareBytes[index]; } return hashCode; } public String toString() { return new String(contentBytes); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineCache.java000066400000000000000000000013571177412531300305440ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; /** * @author Marc Strapetz */ public interface QSequenceLineCache { int getLineCount(); void addLine(QSequenceLine line) throws IOException; QSequenceLine getLine(int index) throws IOException; int getLineHash(int index) throws IOException; void close() throws IOException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineFileSystemCache.java000066400000000000000000000055431177412531300325520ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.IOException; import java.io.InputStream; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ final class QSequenceLineFileSystemCache implements QSequenceLineCache { // Static ================================================================= public static QSequenceLineFileSystemCache create(QSequenceLineRAData data, QSequenceLineTempDirectoryFactory tempDirectoryFactory, int maximumBytesInMemory, int maximumSegmentSize, QSequenceLineSimplifier simplifier) throws IOException { final QSequenceLineFileSystemCache cache = new QSequenceLineFileSystemCache(data, tempDirectoryFactory, maximumBytesInMemory, maximumSegmentSize, simplifier); final QSequenceLineReader reader = new QSequenceLineReader(); final InputStream stream = data.read(0, data.length()); reader.read(stream, cache, simplifier); stream.close(); return cache; } // Fields ================================================================= private final QSequenceLineRAData data; private final QSequenceLineSimplifier simplifier; private final QSequenceLineFileSystemCacheSegments segments; private int lineCount; // Setup ================================================================== private QSequenceLineFileSystemCache(QSequenceLineRAData data, QSequenceLineTempDirectoryFactory tempDirectoryFactory, int maximumBytesInMemory, int maximumSegmentSize, QSequenceLineSimplifier simplifier) { this.data = data; this.simplifier = simplifier; this.segments = new QSequenceLineFileSystemCacheSegments(tempDirectoryFactory, maximumBytesInMemory, maximumSegmentSize); } // Implemented ============================================================ public void close() throws IOException { segments.close(); } public void addLine(QSequenceLine line) throws IOException { if (lineCount >= Integer.MAX_VALUE) { throw new IOException("Too many lines."); } segments.setFromLengthHash(lineCount, line.getFrom(), line.getContentLength(), line.getCompareHash()); lineCount++; } public int getLineCount() { return lineCount; } public QSequenceLine getLine(int index) throws IOException { final long from = segments.getFrom(index); final int length = segments.getLength(index); final byte[] bytes = new byte[length]; data.get(bytes, from, length); return new QSequenceLine(from, bytes, simplifier); } public int getLineHash(int index) throws IOException { return segments.getHash(index); } }QSequenceLineFileSystemCacheSegment.java000066400000000000000000000060141177412531300340100ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ class QSequenceLineFileSystemCacheSegment { // Fields ================================================================= private final long segmentIndex; private final int maximumEntryCount; private long[] froms; private int[] lengths; private int[] hashes; // Setup ================================================================== public QSequenceLineFileSystemCacheSegment(long segmentIndex, int maximumEntryCount) { this.segmentIndex = segmentIndex; this.maximumEntryCount = maximumEntryCount; this.froms = new long[maximumEntryCount]; this.lengths = new int[maximumEntryCount]; this.hashes = new int[maximumEntryCount]; } // Accessing ============================================================== public boolean isLoaded() { return froms != null; } public long getFrom(int index) { return froms[index]; } public int getLength(int index) { return lengths[index]; } public int getHash(int index) { return hashes[index]; } public void setFromLengthHash(int index, long from, int length, int hash) { froms[index] = from; lengths[index] = length; hashes[index] = hash; } public void load(RandomAccessFile file) throws IOException { froms = new long[maximumEntryCount]; lengths = new int[maximumEntryCount]; hashes = new int[maximumEntryCount]; final byte[] bytes = new byte[maximumEntryCount * QSequenceLineMedia.SEGMENT_ENTRY_SIZE]; file.seek(segmentIndex * maximumEntryCount * QSequenceLineMedia.SEGMENT_ENTRY_SIZE); file.readFully(bytes); final ByteArrayInputStream bis = new ByteArrayInputStream(bytes); final DataInputStream is = new DataInputStream(bis); for (int index = 0; index < maximumEntryCount; index++) { froms[index] = is.readLong(); lengths[index] = is.readInt(); hashes[index] = is.readInt(); } } public void unload(RandomAccessFile file) throws IOException { final ByteArrayOutputStream bos = new ByteArrayOutputStream(maximumEntryCount * QSequenceLineMedia.SEGMENT_ENTRY_SIZE); final DataOutputStream os = new DataOutputStream(bos); for (int index = 0; index < maximumEntryCount; index++) { os.writeLong(froms[index]); os.writeInt(lengths[index]); os.writeInt(hashes[index]); } final byte[] bytes = bos.toByteArray(); QSequenceAssert.assertEquals(maximumEntryCount * QSequenceLineMedia.SEGMENT_ENTRY_SIZE, bytes.length); final long offset = segmentIndex * maximumEntryCount * QSequenceLineMedia.SEGMENT_ENTRY_SIZE; file.seek(offset); file.write(bytes); froms = null; lengths = null; hashes = null; } } QSequenceLineFileSystemCacheSegments.java000066400000000000000000000112301177412531300341670ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import de.regnis.q.sequence.core.QSequenceAssert; /** * @author Marc Strapetz */ class QSequenceLineFileSystemCacheSegments { // Fields ================================================================= private final QSequenceLineTempDirectoryFactory tempDirectoryFactory; private final int maximumEntriesPerSegment; private final int maximumSegmentsInMemory; private final List segments; private final List memorySegments; private File filePath; private RandomAccessFile file; // Setup ================================================================== public QSequenceLineFileSystemCacheSegments(QSequenceLineTempDirectoryFactory tempDirectoryFactory, int maximumBytesInMemory, int segmentBytesSize) { QSequenceAssert.assertTrue(segmentBytesSize >= QSequenceLineMedia.SEGMENT_ENTRY_SIZE); QSequenceAssert.assertTrue(maximumBytesInMemory >= segmentBytesSize); this.tempDirectoryFactory = tempDirectoryFactory; this.maximumEntriesPerSegment = segmentBytesSize / QSequenceLineMedia.SEGMENT_ENTRY_SIZE; this.maximumSegmentsInMemory = maximumBytesInMemory / (maximumEntriesPerSegment * QSequenceLineMedia.SEGMENT_ENTRY_SIZE); this.segments = new ArrayList(); this.memorySegments = new LinkedList(); final QSequenceLineFileSystemCacheSegment segment = new QSequenceLineFileSystemCacheSegment(0, maximumEntriesPerSegment); segments.add(segment); memorySegments.add(segment); } // Accessing ============================================================== public long getFrom(int index) throws IOException { final int segmentIndex = index / maximumEntriesPerSegment; final int relativeIndex = index % maximumEntriesPerSegment; return getSegment(segmentIndex).getFrom(relativeIndex); } public int getLength(int index) throws IOException { final int segmentIndex = index / maximumEntriesPerSegment; final int relativeIndex = index % maximumEntriesPerSegment; return getSegment(segmentIndex).getLength(relativeIndex); } public int getHash(int index) throws IOException { final int segmentIndex = index / maximumEntriesPerSegment; final int relativeIndex = index % maximumEntriesPerSegment; return getSegment(segmentIndex).getHash(relativeIndex); } public void setFromLengthHash(int index, long from, int length, int hash) throws IOException { final int segmentIndex = index / maximumEntriesPerSegment; final int relativeIndex = index % maximumEntriesPerSegment; final QSequenceLineFileSystemCacheSegment segment = getSegment(segmentIndex); segment.setFromLengthHash(relativeIndex, from, length, hash); } public void close() throws IOException { if (file == null) { return; } file.close(); filePath.delete(); tempDirectoryFactory.close(); } // Utils ================================================================== private QSequenceLineFileSystemCacheSegment getSegment(int segmentIndex) throws IOException { if (segmentIndex >= segments.size()) { final QSequenceLineFileSystemCacheSegment segment = new QSequenceLineFileSystemCacheSegment(segmentIndex, maximumEntriesPerSegment); segments.add(segment); memorySegments.add(0, segment); maybeUnloadSegments(); return segment; } final QSequenceLineFileSystemCacheSegment segment = (QSequenceLineFileSystemCacheSegment)segments.get(segmentIndex); if (!segment.isLoaded()) { segment.load(getFile()); memorySegments.add(0, segment); maybeUnloadSegments(); } return segment; } private void maybeUnloadSegments() throws IOException { while (memorySegments.size() > maximumSegmentsInMemory) { final QSequenceLineFileSystemCacheSegment segment = (QSequenceLineFileSystemCacheSegment)memorySegments.remove(memorySegments.size() - 1); segment.unload(getFile()); } } private RandomAccessFile getFile() throws IOException { if (file == null) { final File tempDirectory = tempDirectoryFactory.getTempDirectory(); if (!tempDirectory.isDirectory()) { tempDirectory.mkdirs(); } filePath = File.createTempFile("sequence", null, tempDirectory); file = QSequenceLineRandomAccessFileFactory.createRandomAccessFile(filePath, "rw"); } return file; } } QSequenceLineFixedTempDirectoryFactory.java000066400000000000000000000021361177412531300345600ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.File; import java.io.IOException; /** * @author Marc Strapetz */ public class QSequenceLineFixedTempDirectoryFactory implements QSequenceLineTempDirectoryFactory { // Fields ================================================================= private final File tempDirectory; // Setup ================================================================== public QSequenceLineFixedTempDirectoryFactory(File tempDirectory) { this.tempDirectory = tempDirectory; } // Implemented ============================================================ public File getTempDirectory() throws IOException { return tempDirectory; } public void close() { } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineMedia.java000066400000000000000000000223121177412531300305520ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.IOException; import java.io.InputStream; import java.util.List; import de.regnis.q.sequence.QSequenceDifference; import de.regnis.q.sequence.QSequenceDifferenceBlockShifter; import de.regnis.q.sequence.line.simplifier.*; import de.regnis.q.sequence.core.QSequenceAssert; import de.regnis.q.sequence.core.QSequenceDummyCanceller; import de.regnis.q.sequence.core.QSequenceException; import de.regnis.q.sequence.media.QSequenceCachableMedia; import de.regnis.q.sequence.media.QSequenceCachingMedia; import de.regnis.q.sequence.media.QSequenceDiscardingMedia; import de.regnis.q.sequence.media.QSequenceDiscardingMediaNoConfusionDectector; import de.regnis.q.sequence.media.QSequenceMediaComparer; import de.regnis.q.sequence.media.QSequenceMediaDummyIndexTransformer; /** * @author Marc Strapetz */ public final class QSequenceLineMedia implements QSequenceCachableMedia, QSequenceMediaComparer { // Constants ============================================================== public static final int FILE_SEGMENT_SIZE = 16384; public static final int SEGMENT_ENTRY_SIZE = 16; public static final int MEMORY_THRESHOLD; public static final double SEARCH_DEPTH_EXPONENT; static { MEMORY_THRESHOLD = parseMemoryTreshold(System.getProperty("q.sequence.memory-threshold", "1M")); } static { if (System.getProperty("q.sequence.search-depth-exponent") != null) { SEARCH_DEPTH_EXPONENT = Math.max(0.1, Math.min(1.0, Double.parseDouble(System.getProperty("q.sequence.search-depth-exponent")))); } else { SEARCH_DEPTH_EXPONENT = .5; } } // Static ================================================================= public static QSequenceLineCache readLines(QSequenceLineRAData data) throws IOException { if (data.length() <= MEMORY_THRESHOLD) { final InputStream stream = data.read(0, data.length()); try { return QSequenceLineMemoryCache.read(stream, new QSequenceLineDummySimplifier()); } finally { stream.close(); } } return QSequenceLineFileSystemCache.create(data, new QSequenceLineSystemTempDirectoryFactory(), MEMORY_THRESHOLD, FILE_SEGMENT_SIZE, new QSequenceLineDummySimplifier()); } public static QSequenceLineResult createBlocks(QSequenceLineRAData leftData, QSequenceLineRAData rightData) throws IOException, QSequenceException { return createBlocks(leftData, rightData, new QSequenceLineDummySimplifier()); } public static QSequenceLineResult createBlocks(QSequenceLineRAData leftData, QSequenceLineRAData rightData, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { return createBlocks(leftData, rightData, MEMORY_THRESHOLD, FILE_SEGMENT_SIZE, SEARCH_DEPTH_EXPONENT, new QSequenceLineSystemTempDirectoryFactory(), simplifier); } public static QSequenceLineResult createBlocks(QSequenceLineRAData leftData, QSequenceLineRAData rightData, int memoryThreshold, int fileSegmentSize, double searchDepthExponent, QSequenceLineTempDirectoryFactory tempDirectoryFactory, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { if (leftData.length() <= memoryThreshold && rightData.length() <= memoryThreshold) { final InputStream leftStream = leftData.read(0, leftData.length()); final InputStream rightStream = rightData.read(0, rightData.length()); try { return createBlocksInMemory(leftStream, rightStream, searchDepthExponent, simplifier); } finally { leftStream.close(); rightStream.close(); } } return createBlocksInFilesystem(leftData, rightData, tempDirectoryFactory, searchDepthExponent, memoryThreshold, fileSegmentSize, simplifier); } static QSequenceLineResult createBlocksInMemory(InputStream leftStream, InputStream rightStream, double searchDepthExponent, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { final QSequenceLineMemoryCache leftCache = QSequenceLineMemoryCache.read(leftStream, simplifier); final QSequenceLineMemoryCache rightCache = QSequenceLineMemoryCache.read(rightStream, simplifier); final QSequenceLineMedia lineMedia = new QSequenceLineMedia(leftCache, rightCache); final QSequenceCachingMedia cachingMedia = new QSequenceCachingMedia(lineMedia, new QSequenceDummyCanceller()); final QSequenceDiscardingMedia discardingMedia = new QSequenceDiscardingMedia(cachingMedia, new QSequenceDiscardingMediaNoConfusionDectector(true), new QSequenceDummyCanceller()); final List blocks = new QSequenceDifference(discardingMedia, discardingMedia, getSearchDepth(lineMedia, searchDepthExponent)).getBlocks(); new QSequenceDifferenceBlockShifter(cachingMedia, cachingMedia).shiftBlocks(blocks); return new QSequenceLineResult(blocks, leftCache, rightCache); } static QSequenceLineResult createBlocksInFilesystem(QSequenceLineRAData leftData, QSequenceLineRAData rightData, QSequenceLineTempDirectoryFactory tempDirectoryFactory, double searchDepthExponent, int memoryThreshold, int fileSegmentSize, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { final QSequenceLineFileSystemCache leftCache = QSequenceLineFileSystemCache.create(leftData, tempDirectoryFactory, memoryThreshold, fileSegmentSize, simplifier); final QSequenceLineFileSystemCache rightCache = QSequenceLineFileSystemCache.create(rightData, tempDirectoryFactory, memoryThreshold, fileSegmentSize, simplifier); final QSequenceLineMedia lineMedia = new QSequenceLineMedia(leftCache, rightCache); final List blocks = new QSequenceDifference(lineMedia, new QSequenceMediaDummyIndexTransformer(lineMedia), getSearchDepth(lineMedia, searchDepthExponent)).getBlocks(); new QSequenceDifferenceBlockShifter(lineMedia, lineMedia).shiftBlocks(blocks); return new QSequenceLineResult(blocks, leftCache, rightCache); } // Fields ================================================================= private final QSequenceLineCache leftCache; private final QSequenceLineCache rightCache; // Setup ================================================================== public QSequenceLineMedia(QSequenceLineCache leftCache, QSequenceLineCache rightCache) { this.leftCache = leftCache; this.rightCache = rightCache; } // Implemented ============================================================ public int getLeftLength() { return leftCache.getLineCount(); } public int getRightLength() { return rightCache.getLineCount(); } public Object getMediaLeftObject(int index) throws QSequenceException { try { return leftCache.getLine(index); } catch (IOException ex) { throw new QSequenceException(ex); } } public Object getMediaRightObject(int index) throws QSequenceException { try { return rightCache.getLine(index); } catch (IOException ex) { throw new QSequenceException(ex); } } public boolean equals(int leftIndex, int rightIndex) throws QSequenceException { try { final int leftHash = leftCache.getLineHash(leftIndex); final int rightHash = rightCache.getLineHash(rightIndex); if (leftHash != 0 && rightHash != 0 && leftHash != rightHash) { return false; } return leftCache.getLine(leftIndex).equals(rightCache.getLine(rightIndex)); } catch (IOException ex) { throw new QSequenceException(ex); } } public boolean equalsLeft(int left1, int left2) throws QSequenceException { try { return leftCache.getLine(left1).equals(leftCache.getLine(left2)); } catch (IOException ex) { throw new QSequenceException(ex); } } public boolean equalsRight(int right1, int right2) throws QSequenceException { try { return rightCache.getLine(right1).equals(rightCache.getLine(right2)); } catch (IOException ex) { throw new QSequenceException(ex); } } // Utils ================================================================== private static int getSearchDepth(QSequenceLineMedia lineMedia, double searchDepthExponent) { QSequenceAssert.assertTrue(searchDepthExponent >= 0.0 && searchDepthExponent <= 1.0); if (searchDepthExponent == 1.0) { return Integer.MAX_VALUE; } return Math.max(256, (int)Math.pow(lineMedia.getLeftLength() + lineMedia.getRightLength(), searchDepthExponent)); } private static int parseMemoryTreshold(String value) { if (value == null) { value = "1M"; } value = value.toLowerCase(); int factor = 1; if (value.endsWith("m")) { value = value.substring(0, value.length() - 1); factor = 1048576; } else if (value.endsWith("mb")) { value = value.substring(0, value.length() - 2); factor = 1048576; } else if (value.endsWith("k")) { value = value.substring(0, value.length() - 1); factor = 1024; } else if (value.endsWith("kb")) { value = value.substring(0, value.length() - 2); factor = 1024; } try { int amount = Integer.parseInt(value); amount = factor * amount; if (amount < FILE_SEGMENT_SIZE) { amount = FILE_SEGMENT_SIZE; } return amount; } catch (NumberFormatException e) { return parseMemoryTreshold(null); } } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineMemoryCache.java000066400000000000000000000031641177412531300317330ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import java.util.*; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ final class QSequenceLineMemoryCache implements QSequenceLineCache { // Constants ============================================================== public static QSequenceLineMemoryCache read(InputStream is, QSequenceLineSimplifier simplifier) throws IOException { final QSequenceLineMemoryCache cache = new QSequenceLineMemoryCache(); final QSequenceLineReader reader = new QSequenceLineReader(); reader.read(is, cache, simplifier); return cache; } // Fields ================================================================= private final List lines; // Setup ================================================================== public QSequenceLineMemoryCache() { this.lines = new ArrayList(); } // Implemented ============================================================ public void addLine(QSequenceLine line) { lines.add(line); } public int getLineCount() { return lines.size(); } public int getLineHash(int index) { return 0; } public QSequenceLine getLine(int index) { return (QSequenceLine)lines.get(index); } public void close() { } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineRAByteData.java000066400000000000000000000031031177412531300314500ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; /** * @author Marc Strapetz */ public final class QSequenceLineRAByteData implements QSequenceLineRAData { // Constants ============================================================== public static QSequenceLineRAByteData create(InputStream is) throws IOException { final ByteArrayOutputStream os = new ByteArrayOutputStream(); for (; ;) { final int b = is.read(); if (b == -1) { break; } os.write(b); } return new QSequenceLineRAByteData(os.toByteArray()); } // Fields ================================================================= private final byte[] bytes; // Setup ================================================================== public QSequenceLineRAByteData(byte[] bytes) { this.bytes = bytes; } // Implemented ============================================================ public long length() { return bytes.length; } public void get(byte[] bytes, long offset, long length) { System.arraycopy(this.bytes, (int)offset, bytes, 0, (int)length); } public InputStream read(long offset, long length) { return new ByteArrayInputStream(bytes, (int)offset, (int)length); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineRAData.java000066400000000000000000000013051177412531300306260ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; /** * @author Marc Strapetz */ public interface QSequenceLineRAData { long length() throws IOException; void get(byte[] bytes, long offset, long length) throws IOException; InputStream read(long offset, long length) throws IOException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineRAFileData.java000066400000000000000000000027451177412531300314370ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; /** * @author Marc Strapetz */ public final class QSequenceLineRAFileData implements QSequenceLineRAData { // Fields ================================================================= private final RandomAccessFile randomAccessFile; private QSequenceLineRAFileDataStream stream; // Setup ================================================================== public QSequenceLineRAFileData(RandomAccessFile randomAccessFile) { this.randomAccessFile = randomAccessFile; } // Implemented ============================================================ public long length() throws IOException { return randomAccessFile.length(); } public void get(byte[] bytes, long offset, long length) throws IOException { randomAccessFile.seek(offset); randomAccessFile.read(bytes, 0, (int)length); } public InputStream read(long offset, long length) { if (stream != null) { stream.reset(offset, (int)length); } else { stream = new QSequenceLineRAFileDataStream(randomAccessFile, offset, (int)length); } return stream; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineRAFileDataStream.java000066400000000000000000000034101177412531300326010ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; /** * @author Marc Strapetz */ final class QSequenceLineRAFileDataStream extends InputStream { // Fields ================================================================= private final RandomAccessFile myFile; private long offset; private int length; // Setup ================================================================== public QSequenceLineRAFileDataStream(RandomAccessFile myFile, long offset, int length) { this.myFile = myFile; this.length = length; this.offset = offset; } // Implemented ============================================================ public int read() throws IOException { byte[] buffer = new byte[]{-1}; read(buffer, 0, 1); return buffer[0] & 0xFF; } public int read(byte[] buffer, int userOffset, int userLength) throws IOException { if (length <= 0) { return -1; } int available = (int)(myFile.length() - offset); int toRead = Math.min(available, length); toRead = Math.min(userLength, toRead); length -= toRead; long pos = myFile.length(); myFile.seek(offset); int result = myFile.read(buffer, userOffset, toRead); myFile.seek(pos); offset += toRead; return result; } // Accessing ============================================================== public void reset(long offset, int length) { this.offset = offset; this.length = length; } }QSequenceLineRandomAccessFileFactory.java000066400000000000000000000025151177412531300341510ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import java.util.*; /** * @author Marc Strapetz */ public class QSequenceLineRandomAccessFileFactory { // Static ================================================================= private static final Map fileToRaFile = new HashMap(); static { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { for (Iterator it = fileToRaFile.keySet().iterator(); it.hasNext();) { final File file = (File)it.next(); final RandomAccessFile raFile = (RandomAccessFile)fileToRaFile.get(file); try { raFile.close(); file.delete(); } catch (IOException ex) { } } super.run(); } }); } public static RandomAccessFile createRandomAccessFile(File file, String mode) throws FileNotFoundException { final RandomAccessFile raFile = new RandomAccessFile(file, mode); fileToRaFile.put(file, raFile); return raFile; } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineReader.java000066400000000000000000000044471177412531300307460ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ final class QSequenceLineReader { // Fields ================================================================= private byte[] buffer; // Setup ================================================================== public QSequenceLineReader() { this(8192); } public QSequenceLineReader(int initialBufferSize) { buffer = new byte[initialBufferSize]; } // Static ================================================================= public void read(InputStream rawStream, QSequenceLineCache cache, QSequenceLineSimplifier simplifier) throws IOException { final BufferedInputStream stream = new BufferedInputStream(rawStream); try { int pushBack = -1; int from = 0; int length = 0; for (; ;) { int ch = pushBack; if (ch != -1) { pushBack = -1; } else { ch = stream.read(); } if (ch != -1) { append(length, (byte)(ch & 0xff)); length++; } switch (ch) { case '\r': pushBack = stream.read(); if (pushBack == '\n') { append(length, (byte)(pushBack & 0xff)); length++; pushBack = -1; } case '\n': case -1: if (length > 0) { final byte[] bytes; bytes = new byte[length]; System.arraycopy(buffer, 0, bytes, 0, length); cache.addLine(new QSequenceLine(from, bytes, simplifier)); } from = from + length; length = 0; } if (ch == -1) { break; } } } finally { stream.close(); } } // Utils ================================================================== private void append(int position, byte ch) { if (position >= buffer.length) { final byte[] newArray = new byte[buffer.length * 2]; System.arraycopy(buffer, 0, newArray, 0, buffer.length); buffer = newArray; } buffer[position] = ch; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/QSequenceLineResult.java000066400000000000000000000026041177412531300310130ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import java.util.*; /** * @author Marc Strapetz */ public final class QSequenceLineResult { // Fields ================================================================= private final List blocks; private final QSequenceLineCache leftCache; private final QSequenceLineCache rightCache; // Setup ================================================================== public QSequenceLineResult(List blocks, QSequenceLineCache leftCache, QSequenceLineCache rightCache) { this.blocks = blocks; this.leftCache = leftCache; this.rightCache = rightCache; } // Accessing ============================================================== public List getBlocks() { return Collections.unmodifiableList(blocks); } public QSequenceLineCache getLeftCache() { return leftCache; } public QSequenceLineCache getRightCache() { return rightCache; } public void close() throws IOException { leftCache.close(); rightCache.close(); } }QSequenceLineSystemTempDirectoryFactory.java000066400000000000000000000025551177412531300350120ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.File; import java.io.IOException; /** * @author Marc Strapetz */ public class QSequenceLineSystemTempDirectoryFactory implements QSequenceLineTempDirectoryFactory { // Fields ================================================================= private File tempDirectory; // Setup ================================================================== public QSequenceLineSystemTempDirectoryFactory() { } // Implemented ============================================================ public File getTempDirectory() throws IOException { if (tempDirectory == null) { int tries = 0; for (;;) { try { tempDirectory = File.createTempFile("q.sequence.line.", ".temp" + tries); tempDirectory.delete(); break; } catch (IOException ex) { tries++; if (tries > 100) { throw ex; } } } } return tempDirectory; } public void close() { tempDirectory.delete(); } } QSequenceLineTempDirectoryFactory.java000066400000000000000000000012041177412531300335730ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.File; import java.io.IOException; /** * @author Marc Strapetz */ public interface QSequenceLineTempDirectoryFactory { File getTempDirectory() throws IOException; void close(); } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/000077500000000000000000000000001177412531300251565ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffGenerator.java000066400000000000000000000022551177412531300306650ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import de.regnis.q.sequence.line.QSequenceLineRAData; import java.io.*; /** * @author TMate Software Ltd. */ public interface QDiffGenerator { void generateDiffHeader(String item, String leftInfo, String rightInfo, Writer output) throws IOException; void generateTextDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException; void generateTextDiff(RandomAccessFile left, RandomAccessFile right, String encoding, Writer output) throws IOException; void generateTextDiff(QSequenceLineRAData left, QSequenceLineRAData right, String encoding, Writer output) throws IOException; void generateBinaryDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException; } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffGeneratorFactory.java000066400000000000000000000021261177412531300322120ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import java.util.*; /** * @author TMate Software Ltd. */ public interface QDiffGeneratorFactory { public static final String GUTTER_PROPERTY = "gutter"; public static final String EOL_PROPERTY = "eol"; public static final String WHITESPACE_PROPERTY = "whitespace"; public static final String IGNORE_EOL_PROPERTY = "ignore-eol-style"; public static final String IGNORE_SPACE_PROPERTY = "ignore-space"; public static final String IGNORE_SPACE_CHANGE = "space-change"; public static final String IGNORE_ALL_SPACE = "all-space"; public static final String HUNK_DELIMITER = "hunk-delimiter"; public QDiffGenerator createGenerator(Map properties); } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffManager.java000066400000000000000000000067661177412531300303240ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import java.io.*; import java.util.*; /** * @author TMate Software Ltd. */ public final class QDiffManager { // Constants ============================================================== public static final String DEFAULT_TYPE = QDiffNormalGenerator.TYPE; // Static ================================================================= private static Map ourDiffGeneratorFactories; public static void setup() { QDiffNormalGenerator.setup(); QDiffUniGenerator.setup(); } public static QDiffGenerator getDiffGenerator(String type, Map properties) { if (ourDiffGeneratorFactories == null || !ourDiffGeneratorFactories.containsKey(type)) { return null; } return ((QDiffGeneratorFactory)ourDiffGeneratorFactories.get(type)).createGenerator(properties); } public static void generateDiffHeader(String path, String leftInfo, String rightInfo, Writer output, QDiffGenerator generator) throws IOException { if (generator == null || output == null) { throw new NullPointerException("null argument is not accepted by SVNDiffManager.generateDiff()"); } generator.generateDiffHeader(path, leftInfo, rightInfo, output); } public static void generateTextDiff(InputStream left, InputStream right, String encoding, Writer output, QDiffGenerator generator) throws IOException { if (generator == null || left == null || right == null || output == null) { throw new NullPointerException("null argument is not accepted by SVNDiffManager.generateDiff()"); } if (encoding == null) { encoding = System.getProperty("file.encoding", "US-ASCII"); } generator.generateTextDiff(left, right, encoding, output); } public static void generateTextDiff(RandomAccessFile left, RandomAccessFile right, String encoding, Writer output, QDiffGenerator generator) throws IOException { if (generator == null || output == null) { throw new NullPointerException("null argument is not accepted by SVNDiffManager.generateDiff()"); } if (encoding == null) { encoding = System.getProperty("file.encoding", "US-ASCII"); } generator.generateTextDiff(left, right, encoding, output); } public static void generateBinaryDiff(InputStream left, InputStream right, String encoding, Writer output, QDiffGenerator generator) throws IOException { if (generator == null || left == null || right == null || output == null) { throw new NullPointerException("null argument is not accepted by SVNDiffManager.generateDiff()"); } if (encoding == null) { encoding = System.getProperty("file.encoding", "US-ASCII"); } generator.generateBinaryDiff(left, right, encoding, output); } public static void registerDiffGeneratorFactory(QDiffGeneratorFactory factory, String type) { if (factory == null || type == null) { return; } if (ourDiffGeneratorFactories != null && ourDiffGeneratorFactories.containsKey(type)) { return; } if (ourDiffGeneratorFactories == null) { ourDiffGeneratorFactories = new HashMap(); } ourDiffGeneratorFactories.put(type, factory); } // Setup ================================================================== private QDiffManager() { } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffNormalGenerator.java000066400000000000000000000211051177412531300320310ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import java.io.*; import java.util.*; import de.regnis.q.sequence.*; import de.regnis.q.sequence.line.*; /** * @author Ian Sullivan * @author TMate Software Ltd. */ public final class QDiffNormalGenerator extends QDiffSequenceGenerator implements QDiffGeneratorFactory { // Constants ============================================================== public static final String TYPE = "normal"; // Static ================================================================= public static void setup() { QDiffManager.registerDiffGeneratorFactory(new QDiffNormalGenerator(), QDiffNormalGenerator.TYPE); } // Fields ================================================================= private Map myGeneratorsCache; // Setup ================================================================== private QDiffNormalGenerator(Map properties) { super(properties, null); } private QDiffNormalGenerator() { super(null, null); } // Implemented ============================================================ public void generateDiffHeader(String item, String leftInfo, String rightInfo, Writer output) throws IOException { output.write("*** "); output.write(item); output.write(getEOL()); } protected void processBlock(QSequenceDifferenceBlock[] segment, QSequenceLineCache sourceLines, QSequenceLineCache targetLines, String encoding, Writer output) throws IOException { for (int i = 0; i < segment.length; i++) { QSequenceDifferenceBlock block = segment[i]; processBlock(block.getLeftFrom(), block.getLeftTo(), sourceLines, block.getRightFrom(), block.getRightTo(), targetLines, encoding, output); } } public QDiffGenerator createGenerator(Map properties) { if (myGeneratorsCache == null) { myGeneratorsCache = new HashMap(); } QDiffGenerator generator = (QDiffGenerator)myGeneratorsCache.get(properties); if (generator != null) { return generator; } generator = new QDiffNormalGenerator(properties); myGeneratorsCache.put(properties, generator); return generator; } // Accessing ============================================================== protected void processBlock(int sourceStartLine, int sourceEndLine, QSequenceLineCache sourceLines, int targetStartLine, int targetEndLine, QSequenceLineCache targetLines, String encoding, Writer output) throws IOException { if (sourceStartLine > sourceEndLine) { add(sourceStartLine, targetStartLine, targetEndLine, targetLines, encoding, output); } else if (targetStartLine > targetEndLine) { delete(targetStartLine, sourceStartLine, sourceEndLine, sourceLines, encoding, output); } else { change(targetStartLine, targetEndLine, targetLines, sourceStartLine, sourceEndLine, sourceLines, encoding, output); } } protected String displayWhiteSpace(String s) { if (Boolean.TRUE.toString().equals(getProperties().get(QDiffGeneratorFactory.WHITESPACE_PROPERTY))) { s = s.replaceAll("\t", ""); s = s.replaceAll(" ", "."); } return s; } /* * Normal diff output is a series of one or more blocks in the following * format change-command < target-file-line < target-file-line... --- > * source-file-line > source-file-line... There are three types of change * commands. Each consists of a line number or comma-separated range of * lines in the target file, a single character indicating the kind of * change to make, and a line number or comma-separated range of lines in * the source file. All line numbers are the original line numbers in each * file. */ /** * Handles a delete of lines from the target. * * @param deleteAt the line where the lines would have appeared in the source (0 based) * @param deleteStart first line deleted from target (0 based). * @param deleteEnd last line deleted from target (0 based). * @param deleteLines all the lines from the target file. Could be accessed with deleteStart and * deleteEnd to identify the deleted lines. */ protected void delete(int deleteAt, int deleteStart, int deleteEnd, QSequenceLineCache deleteLines, String encoding, Writer output) throws IOException { /* * Change command is in the format `rdl' Delete the lines in range r * from the target file; line l is where they would have appeared in the * source file had they not been deleted. For example, `5,7d3' means * delete lines 5--7 of target file; or, if changing source file into * target file, append lines 5--7 of target file after line 3 of source * file. */ // deleteStart and deleteEnd are 0 based, display a 1 based value. int displayStart = deleteStart + 1; int displayEnd = deleteEnd + 1; int displayAt = deleteAt + 1; println(displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : "") + "d" + displayAt, output); int delLine = deleteStart; while (delLine <= deleteEnd) { print("<" + displayWhiteSpace(printLine(deleteLines.getLine(delLine++), encoding)), output); } } /** * Handles the addition of lines to source. * * @param addAt the line where the new lines would be added to target (0 based) * @param addStart the first line added from source (0 based) * @param addEnd the last line added from source (0 based) * @param addLines all the lines from the source file. Could be accessed with addStart and * addEnd to identify the added lines. */ protected void add(int addAt, int addStart, int addEnd, QSequenceLineCache addLines, String encoding, Writer output) throws IOException { /* * Change command is in the format `lar' Add the lines in range r of the * source file after line l of the target file. For example, `8a12,15' * means append lines 12--15 of source file after line 8 of target file; * or, if changing source file into target file, delete lines 12--15 of * source file. */ int displayStart = addStart + 1; int displayEnd = addEnd + 1; int displayAt = addAt + 1; println(displayAt + "a" + displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : ""), output); int addLine = addStart; while (addLine <= addEnd) { print(">" + displayWhiteSpace(printLine(addLines.getLine(addLine++), encoding)), output); } } /** * Handles a change of a range of lines in target to a range of lines in source. * * @param replaceStart the first line in target that will be replaced (0 based) * @param replaceEnd the last line in target that will be replaced (0 based) * @param replaceLines all the lines in target * @param replaceWithStart the first line in source to that will replace the lines in target (0 based) * @param replaceWithEnd the last line in source to that will replace the lines in target (0 based) * @param replaceWithLines all the lines in source */ protected void change(int replaceStart, int replaceEnd, QSequenceLineCache replaceLines, int replaceWithStart, int replaceWithEnd, QSequenceLineCache replaceWithLines, String encoding, Writer output) throws IOException { /* * Change command is in the format `fct' Replace the lines in range f of * the target file with lines in range t of the source file. This is * like a combined add and delete, but more compact. For example, * `5,7c8,10' means change lines 5--7 of target file to read as lines * 8--10 of source file; or, if changing source file into target file, * change lines 8--10 of source file to read as lines 5--7 of target * file. */ int displayStart = replaceStart + 1; int displayEnd = replaceEnd + 1; int displayWithStart = replaceWithStart + 1; int displayWithEnd = replaceWithEnd + 1; println(displayStart + ((displayEnd != displayStart) ? ("," + displayEnd) : "") + "c" + displayWithStart + ((displayWithEnd != displayWithStart) ? ("," + displayWithEnd) : ""), output); int replaceLine = replaceStart; while (replaceLine <= replaceEnd) { print("<" + displayWhiteSpace(printLine(replaceLines.getLine(replaceLine++), encoding)), output); } println("---", output); int replaceWithLine = replaceWithStart; while (replaceWithLine <= replaceWithEnd) { print(">" + displayWhiteSpace(printLine(replaceWithLines.getLine(replaceWithLine++), encoding)), output); } } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffSequenceGenerator.java000066400000000000000000000153531177412531300323610ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import java.io.*; import java.util.*; import de.regnis.q.sequence.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.line.*; import de.regnis.q.sequence.line.simplifier.*; /** * @author Ian Sullivan * @author TMate Software Ltd. */ public abstract class QDiffSequenceGenerator implements QDiffGenerator { // Abstract =============================================================== protected abstract void processBlock(QSequenceDifferenceBlock[] segment, QSequenceLineCache sourceLines, QSequenceLineCache targetLines, String encoding, Writer output) throws IOException; // Fields ================================================================= private final String header; private Map myProperties; // Setup ================================================================== protected QDiffSequenceGenerator(Map properties, String header) { this.header = header; myProperties = properties == null ? Collections.EMPTY_MAP : properties; myProperties = Collections.unmodifiableMap(myProperties); } // Implemented ============================================================ public void generateBinaryDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException { println("Binary files are different", output); } public void generateTextDiff(InputStream left, InputStream right, String encoding, Writer output) throws IOException { generateTextDiff(QSequenceLineRAByteData.create(left), QSequenceLineRAByteData.create(right), encoding, output); } public void generateTextDiff(QSequenceLineRAData left, QSequenceLineRAData right, String encoding, Writer output) throws IOException { final QSequenceLineResult result; try { result = QSequenceLineMedia.createBlocks(left, right, getSimplifier()); } catch (QSequenceException ex) { throw new IOException(ex.getMessage()); } try { final List combinedBlocks = combineBlocks(result.getBlocks(), getGutter()); boolean headerWritten = false; for (Iterator it = combinedBlocks.iterator(); it.hasNext();) { List segment = (List)it.next(); if (segment.isEmpty()) { continue; } if (!headerWritten && header != null) { headerWritten = true; output.write(header); } QSequenceDifferenceBlock[] segmentBlocks = (QSequenceDifferenceBlock[])segment.toArray(new QSequenceDifferenceBlock[segment.size()]); processBlock(segmentBlocks, result.getLeftCache(), result.getRightCache(), encoding, output); } } finally { result.close(); } } public void generateTextDiff(RandomAccessFile left, RandomAccessFile right, String encoding, Writer output) throws IOException { QSequenceLineRAData leftData = null, rightData = null; if (left == null) { leftData = new QSequenceLineRAByteData(new byte[0]); } else { leftData = new QSequenceLineRAFileData(left); } if (right == null) { rightData = new QSequenceLineRAByteData(new byte[0]); } else { rightData = new QSequenceLineRAFileData(right); } generateTextDiff(leftData, rightData, encoding, output); } // Accessing ============================================================== protected Map getProperties() { return myProperties; } protected String getHunkDelimiter() { final Object hunkDelimiter = getProperties().get(QDiffGeneratorFactory.HUNK_DELIMITER); if (hunkDelimiter != null && hunkDelimiter instanceof String) { return (String) hunkDelimiter; } else { return "@@"; } } protected String getEOL() { if (getProperties().get(QDiffGeneratorFactory.EOL_PROPERTY) instanceof String) { return (String)getProperties().get(QDiffGeneratorFactory.EOL_PROPERTY); } return System.getProperty("line.separator", "\n"); } protected QSequenceLineSimplifier getSimplifier() { final Object ignore = getProperties().get(QDiffGeneratorFactory.IGNORE_SPACE_PROPERTY); final QSequenceLineSimplifier baseSimplifier; if (QDiffGeneratorFactory.IGNORE_ALL_SPACE.equals(ignore)) { baseSimplifier = new QSequenceLineWhiteSpaceSkippingSimplifier(); } else if (QDiffGeneratorFactory.IGNORE_SPACE_CHANGE.equals(ignore)) { baseSimplifier = new QSequenceLineWhiteSpaceReducingSimplifier(); } else { baseSimplifier = new QSequenceLineDummySimplifier(); } if (getProperties().containsKey(QDiffGeneratorFactory.IGNORE_EOL_PROPERTY)) { return new QSequenceLineTeeSimplifier(baseSimplifier, new QSequenceLineEOLUnifyingSimplifier()); } return baseSimplifier; } protected int getGutter() { Object gutterStr = getProperties().get(QDiffGeneratorFactory.GUTTER_PROPERTY); if (gutterStr == null) { return 0; } try { return Integer.parseInt(gutterStr.toString()); } catch (NumberFormatException e) { } return 0; } protected String printLine(QSequenceLine line, String encoding) throws IOException { String str = new String(line.getContentBytes(), encoding); return str; } protected void println(Writer output) throws IOException { output.write(getEOL()); } protected void println(String str, Writer output) throws IOException { if (str != null) { output.write(str); } output.write(getEOL()); } protected void print(String str, Writer output) throws IOException { if (str != null) { output.write(str); } } // Utils ================================================================== private static List combineBlocks(List blocksList, int gutter) { List combinedBlocks = new LinkedList(); List currentList = new LinkedList(); QSequenceDifferenceBlock lastBlock = null; for (Iterator blocks = blocksList.iterator(); blocks.hasNext();) { QSequenceDifferenceBlock currentBlock = (QSequenceDifferenceBlock)blocks.next(); if (lastBlock != null) { final int leftDifference = currentBlock.getLeftFrom() - 1 - lastBlock.getLeftTo(); final int rightDifference = currentBlock.getRightFrom() - 1 - lastBlock.getRightTo(); if (leftDifference > 2 * gutter && rightDifference > 2 * gutter) { combinedBlocks.add(currentList); currentList = new LinkedList(); } } currentList.add(currentBlock); lastBlock = currentBlock; } if (!combinedBlocks.contains(currentList)) { combinedBlocks.add(currentList); } return combinedBlocks; } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/diff/QDiffUniGenerator.java000066400000000000000000000134531177412531300313430ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.diff; import java.io.*; import java.util.*; import de.regnis.q.sequence.*; import de.regnis.q.sequence.line.*; /** * @author Ian Sullivan * @author TMate Software Ltd. */ public final class QDiffUniGenerator extends QDiffSequenceGenerator implements QDiffGeneratorFactory { // Constants ============================================================== public static final String TYPE = "unified"; // Static ================================================================= public static void setup() { QDiffManager.registerDiffGeneratorFactory(new QDiffUniGenerator(), QDiffUniGenerator.TYPE); } // Fields ================================================================= private Map myGeneratorsCache; // Setup ================================================================== public QDiffUniGenerator(Map properties, String header) { super(initProperties(properties), header); } private QDiffUniGenerator() { super(null, null); } // Implemented ============================================================ public void generateDiffHeader(String item, String leftInfo, String rightInfo, Writer output) throws IOException { leftInfo = leftInfo == null ? "" : "\t" + leftInfo; rightInfo = rightInfo == null ? "" : "\t" + rightInfo; println("--- " + item + leftInfo, output); println("+++ " + item + rightInfo, output); } protected void processBlock(QSequenceDifferenceBlock[] segment, QSequenceLineCache sourceLines, QSequenceLineCache targetLines, String encoding, Writer output) throws IOException { int gutter = getGutter(); // header StringBuffer header = new StringBuffer(); header.append(getHunkDelimiter()); int sourceStartLine = segment[0].getLeftFrom(); int sourceEndLine = segment[segment.length - 1].getLeftTo(); int targetStartLine = segment[0].getRightFrom(); int targetEndLine = segment[segment.length - 1].getRightTo(); int leftStart = Math.max(sourceStartLine - gutter, 0); int rightStart = Math.max(targetStartLine - gutter, 0); int leftEnd = Math.min(sourceEndLine + gutter, sourceLines.getLineCount() - 1); int rightEnd = Math.min(targetEndLine + gutter, targetLines.getLineCount() - 1); if (leftStart + 1 >= 0 && (leftEnd - leftStart + 1) >= 0) { header.append(" -"); if (leftStart == 0 && leftEnd < 0) { header.append("0,0"); } else { header.append(leftStart + 1); if (leftEnd - leftStart + 1 > 1) { header.append(","); header.append(leftEnd - leftStart + 1); } } } if (rightStart + 1 > 0 && rightEnd - rightStart + 1 > 0) { header.append(" +"); header.append(rightStart + 1); if (rightEnd - rightStart + 1 > 1) { header.append(","); header.append(rightEnd - rightStart + 1); } } else { header.append(" +0,0"); } header.append(" "); header.append(getHunkDelimiter()); println(header.toString(), output); // print gutter context lines before blocks. for (int i = leftStart; i < sourceStartLine; i++) { print(" " + printLine(sourceLines.getLine(i), encoding), output); } for (int i = 0; i < segment.length; i++) { QSequenceDifferenceBlock block = segment[i]; for (int j = block.getLeftFrom(); j <= block.getLeftTo(); j++) { String line = printLine(sourceLines.getLine(j), encoding); print("-" + line, output); if (j == sourceLines.getLineCount() - 1) { printNoNewLine(output, line); } } for (int j = block.getRightFrom(); j <= block.getRightTo(); j++) { String line = printLine(targetLines.getLine(j), encoding); print("+" + line, output); if (j == targetLines.getLineCount() - 1) { printNoNewLine(output, line); } } // print glue lines resp. final gutter lines int plannedEnd; if (i < segment.length - 1) { plannedEnd = segment[i+1].getLeftFrom() - 1; } else { plannedEnd = block.getLeftTo() + gutter; } int end = Math.min(plannedEnd, sourceLines.getLineCount() - 1); if (i + 1 < segment.length) { end = Math.min(end, segment[i + 1].getLeftFrom() - 1); } for (int j = block.getLeftTo() + 1; j <= end; j++) { String line = printLine(sourceLines.getLine(j), encoding); print(" " + printLine(sourceLines.getLine(j), encoding), output); if (j == sourceLines.getLineCount() - 1) { printNoNewLine(output, line); } } } } public QDiffGenerator createGenerator(Map properties) { if (myGeneratorsCache == null) { myGeneratorsCache = new HashMap(); } QDiffGenerator generator = (QDiffGenerator)myGeneratorsCache.get(properties); if (generator != null) { return generator; } generator = new QDiffUniGenerator(properties, null); myGeneratorsCache.put(properties, generator); return generator; } // Utils ================================================================== private void printNoNewLine(Writer output, String line) throws IOException { if (!line.endsWith("\n") && !line.endsWith("\r")) { println(output); println("\\ No newline at end of file", output); } } private static Map initProperties(Map properties) { if (properties == null || !properties.containsKey(QDiffGeneratorFactory.GUTTER_PROPERTY)) { properties = new HashMap(properties == null ? Collections.EMPTY_MAP : properties); properties.put(QDiffGeneratorFactory.GUTTER_PROPERTY, "3"); } return properties; } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/000077500000000000000000000000001177412531300264115ustar00rootroot00000000000000QSequenceLineDummySimplifier.java000066400000000000000000000013041177412531300347340ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public class QSequenceLineDummySimplifier implements QSequenceLineSimplifier { // Implemented ============================================================ public byte[] simplify(byte[] bytes) { return bytes; } } QSequenceLineEOLUnifyingSimplifier.java000066400000000000000000000016701177412531300357770ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public class QSequenceLineEOLUnifyingSimplifier implements QSequenceLineSimplifier { // Implemented ============================================================ public byte[] simplify(byte[] bytes) { String line = new String(bytes); boolean trimmed = false; while (line.endsWith("\n") || line.endsWith("\r")) { line = line.substring(0, line.length() - 1); trimmed = true; } if (trimmed) { line += "\n"; } return line.getBytes(); } } QSequenceLineSimplifier.java000066400000000000000000000010661177412531300337250ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public interface QSequenceLineSimplifier { byte[] simplify(byte[] bytes); } QSequenceLineTeeSimplifier.java000066400000000000000000000021631177412531300343620ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public class QSequenceLineTeeSimplifier implements QSequenceLineSimplifier { // Fields ================================================================= private final QSequenceLineSimplifier first; private final QSequenceLineSimplifier second; // Setup ================================================================== public QSequenceLineTeeSimplifier(QSequenceLineSimplifier first, QSequenceLineSimplifier second) { this.first = first; this.second = second; } // Implemented ============================================================ public byte[] simplify(byte[] bytes) { return second.simplify(first.simplify(bytes)); } } QSequenceLineWhiteSpaceReducingSimplifier.java000066400000000000000000000025701177412531300373640ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public class QSequenceLineWhiteSpaceReducingSimplifier implements QSequenceLineSimplifier { // Static ================================================================= public static String reduceWhiteSpaces(String text) { final StringBuffer buffer = new StringBuffer(); boolean lastWasWhiteSpace = false; for (int index = 0; index < text.length(); index++) { final char ch = text.charAt(index); if (ch != '\n' && ch != '\r' && Character.isWhitespace(ch)) { lastWasWhiteSpace = true; } else { if (lastWasWhiteSpace) { buffer.append(' '); lastWasWhiteSpace = false; } buffer.append(ch); } } if (lastWasWhiteSpace) { buffer.append(' '); } return buffer.toString(); } // Implemented ============================================================ public byte[] simplify(byte[] bytes) { return reduceWhiteSpaces(new String(bytes)).getBytes(); } } QSequenceLineWhiteSpaceSkippingSimplifier.java000066400000000000000000000022411177412531300374030ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/line/simplifier/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line.simplifier; /** * @author Marc Strapetz */ public class QSequenceLineWhiteSpaceSkippingSimplifier implements QSequenceLineSimplifier { // Static ================================================================= public static String removeWhiteSpaces(String text) { final StringBuffer buffer = new StringBuffer(); for (int index = 0; index < text.length(); index++) { final char ch = text.charAt(index); if (ch != '\n' && ch != '\r' && Character.isWhitespace(ch)) { continue; } buffer.append(ch); } return buffer.toString(); } // Implemented ============================================================ public byte[] simplify(byte[] bytes) { return removeWhiteSpaces(new String(bytes)).getBytes(); } } libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/000077500000000000000000000000001177412531300243765ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceCachableMedia.java000066400000000000000000000013131177412531300314730ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public interface QSequenceCachableMedia extends QSequenceMedia { Object getMediaLeftObject(int index) throws QSequenceException; Object getMediaRightObject(int index) throws QSequenceException; }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceCachableMediaGetter.java000066400000000000000000000013051177412531300326470ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public interface QSequenceCachableMediaGetter { int getMediaLength(QSequenceCachableMedia media); Object getMediaObject(QSequenceCachableMedia media, int index) throws QSequenceException; }QSequenceCachableMediaLeftGetter.java000066400000000000000000000016331177412531300334070ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceCachableMediaLeftGetter implements QSequenceCachableMediaGetter { // Implemented ============================================================ public int getMediaLength(QSequenceCachableMedia media) { return media.getLeftLength(); } public Object getMediaObject(QSequenceCachableMedia media, int index) throws QSequenceException { return media.getMediaLeftObject(index); } }QSequenceCachableMediaRightGetter.java000066400000000000000000000016371177412531300335760ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceCachableMediaRightGetter implements QSequenceCachableMediaGetter { // Implemented ============================================================ public int getMediaLength(QSequenceCachableMedia media) { return media.getRightLength(); } public Object getMediaObject(QSequenceCachableMedia media, int index) throws QSequenceException { return media.getMediaRightObject(index); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceCachingMedia.java000066400000000000000000000036351177412531300313560ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceCachingMedia extends QSequenceIntMedia { // Fields ================================================================= private final QSequenceCachingMediaSymbolMap symbolMap; private final int[] leftSymbols; private final int[] rightSymbols; // Setup ================================================================== public QSequenceCachingMedia(QSequenceCachableMedia media, QSequenceCanceller canceller) throws QSequenceException { super(canceller); this.symbolMap = new QSequenceCachingMediaSymbolMap(media.getLeftLength() + media.getRightLength()); this.leftSymbols = symbolMap.createSymbols(media, new QSequenceCachableMediaLeftGetter()); this.rightSymbols = symbolMap.createSymbols(media, new QSequenceCachableMediaRightGetter()); } // Implemented ============================================================ public int getLeftLength() { return leftSymbols.length; } public int getRightLength() { return rightSymbols.length; } public boolean equals(int leftIndex, int rightIndex) throws QSequenceCancelledException { checkCancelled(); return leftSymbols[leftIndex] == rightSymbols[rightIndex]; } // Accessing ============================================================== public int getSymbolCount() { return symbolMap.getSymbolCount(); } public int[] getLeftSymbols() { return leftSymbols; } public int[] getRightSymbols() { return rightSymbols; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceCachingMediaSymbolMap.java000066400000000000000000000033341177412531300331760ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import java.util.*; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceCachingMediaSymbolMap { // Fields ================================================================= private final Map map; private int symbolCount; // Setup ================================================================== public QSequenceCachingMediaSymbolMap(int maximumSize) { this.map = new HashMap(maximumSize); this.symbolCount = 0; } // Accessing ============================================================== public int getSymbolCount() { return symbolCount; } public int[] createSymbols(QSequenceCachableMedia media, QSequenceCachableMediaGetter mediaGetter) throws QSequenceException { final int length = mediaGetter.getMediaLength(media); final int[] symbols = new int[length]; for (int index = 0; index < length; index++) { final Object object = mediaGetter.getMediaObject(media, index); symbols[index] = getSymbol(object); } return symbols; } // Utils ================================================================== private int getSymbol(Object obj) { Integer symbol = (Integer)map.get(obj); if (symbol == null) { symbol = new Integer(symbolCount); symbolCount++; map.put(obj, symbol); } return symbol.intValue(); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceDiscardingMedia.java000066400000000000000000000051021177412531300320600ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceDiscardingMedia implements QSequenceMedia, QSequenceMediaIndexTransformer { // Fields ================================================================= private final QSequenceIntMedia media; private final QSequenceCanceller canceller; private final QSequenceDiscardingMediaBlock leftBlock; private final QSequenceDiscardingMediaBlock rightBlock; private final int[] undiscardedLeftSymbols; private final int[] undiscardedRightSymbols; private final int undiscardedLeftSymbolCount; private final int undiscardedRightSymbolCount; // Setup ================================================================== public QSequenceDiscardingMedia(QSequenceIntMedia media, QSequenceDiscardingMediaConfusionDetector confusionDetector, QSequenceCanceller canceller) { this.media = media; this.canceller = canceller; this.leftBlock = new QSequenceDiscardingMediaLeftBlock(this.media); this.rightBlock = new QSequenceDiscardingMediaRightBlock(this.media); leftBlock.init(rightBlock, confusionDetector); rightBlock.init(leftBlock, confusionDetector); undiscardedLeftSymbols = leftBlock.getUndiscardedSymbols(); undiscardedLeftSymbolCount = leftBlock.getUndiscardedSymbolCount(); undiscardedRightSymbols = rightBlock.getUndiscardedSymbols(); undiscardedRightSymbolCount = rightBlock.getUndiscardedSymbolCount(); } // Implemented ============================================================ public int getLeftLength() { return undiscardedLeftSymbolCount; } public int getRightLength() { return undiscardedRightSymbolCount; } public boolean equals(int leftIndex, int rightIndex) throws QSequenceCancelledException { canceller.checkCancelled(); return undiscardedLeftSymbols[leftIndex] == undiscardedRightSymbols[rightIndex]; } public int getMediaLeftIndex(int index) { return leftBlock.getMediaIndex(index); } public int getMediaRightIndex(int index) { return rightBlock.getMediaIndex(index); } public int getMediaLeftLength() { return media.getLeftLength(); } public int getMediaRightLength() { return media.getRightLength(); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceDiscardingMediaBlock.java000066400000000000000000000157321177412531300330450ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public abstract class QSequenceDiscardingMediaBlock { // Abstract =============================================================== protected abstract int[] getAllSymbols(QSequenceIntMedia media); // Fields ================================================================= private final QSequenceIntMedia media; private final int[] undiscardedSymbols; private final int[] undiscardedIndices; private int undiscardedSymbolCount; // Setup ================================================================== protected QSequenceDiscardingMediaBlock(QSequenceIntMedia media) { this.media = media; this.undiscardedSymbols = new int[getAllSymbols(media).length]; this.undiscardedIndices = new int[getAllSymbols(media).length]; this.undiscardedSymbolCount = 0; } // Accessing ============================================================== public int getUndiscardedSymbolCount() { return undiscardedSymbolCount; } public int[] getUndiscardedSymbols() { return undiscardedSymbols; } public int getMediaIndex(int index) { return undiscardedIndices[index]; } public void init(QSequenceDiscardingMediaBlock thatBlock, QSequenceDiscardingMediaConfusionDetector confusionDetector) { QSequenceAssert.assertNotNull(confusionDetector); // Set up table of which lines are going to be discarded. final int[] thisAllSymbols = getAllSymbols(media); final int[] thatAllSymbols = thatBlock.getAllSymbols(media); final int[] otherEquivalences = createEquivalences(thatAllSymbols, media); final byte[] discardableMarkers = createDiscardableMarkers(thisAllSymbols, otherEquivalences, confusionDetector); // Don't really discard the provisional lines except when they occur // in a run of discardables, with nonprovisionals at the beginning // and end. // filterDiscardableMarkers(allSymbols, discardableMarkers); for (int index = 0; index < thisAllSymbols.length; ++index) { if (discardableMarkers[index] != 1) { undiscardedSymbols[undiscardedSymbolCount] = thisAllSymbols[index]; undiscardedIndices[undiscardedSymbolCount] = index; undiscardedSymbolCount++; } } } // Utils ================================================================== private static int[] createEquivalences(int[] symbols, QSequenceIntMedia media) { final int[] equivalences = new int[media.getSymbolCount()]; for (int index = 0; index < symbols.length; index++) { equivalences[symbols[index]]++; } return equivalences; } private static byte[] createDiscardableMarkers(int[] symbols, int[] otherEquivalences, QSequenceDiscardingMediaConfusionDetector confusionDetector) { final byte[] discardableMarkers = new byte[symbols.length]; confusionDetector.init(symbols.length); for (int index = 0; index < symbols.length; index++) { final int occurences = otherEquivalences[symbols[index]]; if (confusionDetector.isAbsolute(occurences)) { discardableMarkers[index] = 1; } else if (confusionDetector.isProvisional(occurences)) { discardableMarkers[index] = 2; } } return discardableMarkers; } // --Commented out by Inspection START (17.06.04 15:17): // private static void filterDiscardableMarkers(int[] symbols, byte[] discardableMarkers) { // for (int i = 0; i < symbols.length; i++) { // // Cancel provisional discards not in middle of run of discards. // if (discardableMarkers[i] == 2) { // discardableMarkers[i] = 0; // } // else if (discardableMarkers[i] != 0) { // // We have found a nonprovisional discard. // int j; // final int length; // int provisional = 0; // // // Find end of this run of discardable lines. // // Count how many are provisionally discardable. // for (j = i; j < symbols.length; j++) { // if (discardableMarkers[j] == 0) { // break; // } // if (discardableMarkers[j] == 2) { // provisional++; // } // } // // // Cancel provisional discards at end, and shrink the run. // while (j > i && discardableMarkers[j - 1] == 2) { // discardableMarkers[--j] = 0; // provisional--; // } // // // Now we have the length of a run of discardable lines // // whose first and last are not provisional. // length = j - i; // // // If 1/4 of the lines in the run are provisional, // // cancel discarding of all provisional lines in the run. // if (provisional * 4 > length) { // while (j > i) { // if (discardableMarkers[--j] == 2) { // discardableMarkers[j] = 0; // } // } // } // else { // int consec; // int minimum = 1; // int tem = length / 4; // // // MINIMUM is approximate square root of LENGTH/4. // // A subrun of two or more provisionals can stand // // when LENGTH is at least 16. // // A subrun of 4 or more can stand when LENGTH >= 64. // while ((tem >>= 2) > 0) { // minimum *= 2; // } // minimum++; // // // Cancel any subrun of MINIMUM or more provisionals // // within the larger run. // for (j = 0, consec = 0; j < length; j++) { // if (discardableMarkers[i + j] != 2) { // consec = 0; // } // else if (minimum == ++consec) { // // Back up to start of subrun, to cancel it all. // j -= consec; // } // else if (minimum < consec) { // discardableMarkers[i + j] = 0; // } // } // // // Scan from beginning of run // // until we find 3 or more nonprovisionals in a row // // or until the first nonprovisional at least 8 lines in. // // Until that point, cancel any provisionals. // for (j = 0, consec = 0; j < length; j++) { // if (j >= 8 && discardableMarkers[i + j] == 1) { // break; // } // if (discardableMarkers[i + j] == 2) { // consec = 0; // discardableMarkers[i + j] = 0; // } // else if (discardableMarkers[i + j] == 0) { // consec = 0; // } // else { // consec++; // } // if (consec == 3) { // break; // } // } // // // I advances to the last line of the run. // i += length - 1; // // // Same thing, from end. // for (j = 0, consec = 0; j < length; j++) { // if (j >= 8 && discardableMarkers[i - j] == 1) { // break; // } // if (discardableMarkers[i - j] == 2) { // consec = 0; // discardableMarkers[i - j] = 0; // } // else if (discardableMarkers[i - j] == 0) { // consec = 0; // } // else { // consec++; // } // if (consec == 3) { // break; // } // } // } // } // } // } // --Commented out by Inspection STOP (17.06.04 15:17) }QSequenceDiscardingMediaConfusionDetector.java000066400000000000000000000012121177412531300353550ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; /** * @author Marc Strapetz */ public interface QSequenceDiscardingMediaConfusionDetector { void init(int symbolCount); boolean isAbsolute(int occurences); boolean isProvisional(int occurences); }QSequenceDiscardingMediaLeftBlock.java000066400000000000000000000016131177412531300335720ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; /** * @author Marc Strapetz */ public class QSequenceDiscardingMediaLeftBlock extends QSequenceDiscardingMediaBlock { // Setup ================================================================== public QSequenceDiscardingMediaLeftBlock(QSequenceIntMedia media) { super(media); } // Implemented ============================================================ protected int[] getAllSymbols(QSequenceIntMedia media) { return media.getLeftSymbols(); } }QSequenceDiscardingMediaNoConfusionDectector.java000066400000000000000000000022621177412531300360230ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; /** * @author Marc Strapetz */ public class QSequenceDiscardingMediaNoConfusionDectector implements QSequenceDiscardingMediaConfusionDetector { // Fields ================================================================= private final boolean discardAbsolutes; // Setup ================================================================== public QSequenceDiscardingMediaNoConfusionDectector(boolean discardAbsolutes) { this.discardAbsolutes = discardAbsolutes; } // Implemented ============================================================ public void init(int symbolCount) { } public boolean isAbsolute(int occurences) { return discardAbsolutes && occurences == 0; } public boolean isProvisional(int occurences) { return false; } }QSequenceDiscardingMediaRightBlock.java000066400000000000000000000016201177412531300337530ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; /** * @author Marc Strapetz */ public class QSequenceDiscardingMediaRightBlock extends QSequenceDiscardingMediaBlock { // Setup ================================================================== public QSequenceDiscardingMediaRightBlock(QSequenceIntMedia media) { super(media); } // Implemented ============================================================ protected int[] getAllSymbols(QSequenceIntMedia media) { return media.getRightSymbols(); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceIntMedia.java000066400000000000000000000033051177412531300305460ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public abstract class QSequenceIntMedia implements QSequenceMedia, QSequenceMediaComparer { // Abstract =============================================================== public abstract int getSymbolCount(); public abstract int[] getLeftSymbols(); public abstract int[] getRightSymbols(); // Fields ================================================================= private final QSequenceCanceller canceller; // Setup ================================================================== protected QSequenceIntMedia(QSequenceCanceller canceller) { this.canceller = canceller; } // Implemented ============================================================ public final boolean equalsLeft(int left1, int left2) throws QSequenceCancelledException { checkCancelled(); return getLeftSymbols()[left1] == getLeftSymbols()[left2]; } public final boolean equalsRight(int right1, int right2) throws QSequenceCancelledException { checkCancelled(); return getRightSymbols()[right1] == getRightSymbols()[right2]; } // Accessing ============================================================== public final void checkCancelled() throws QSequenceCancelledException { canceller.checkCancelled(); } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceMediaComparer.java000066400000000000000000000012761177412531300315710ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public interface QSequenceMediaComparer { boolean equalsLeft(int left1, int left2) throws QSequenceException; boolean equalsRight(int right1, int right2) throws QSequenceException; }QSequenceMediaDummyIndexTransformer.java000066400000000000000000000027661177412531300342550ustar00rootroot00000000000000libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceMediaDummyIndexTransformer implements QSequenceMediaIndexTransformer { // Fields ================================================================= private final int mediaLeftLength; private final int mediaRightLength; // Setup ================================================================== public QSequenceMediaDummyIndexTransformer(QSequenceMedia media) { this.mediaLeftLength = media.getLeftLength(); this.mediaRightLength = media.getRightLength(); } public QSequenceMediaDummyIndexTransformer(int mediaLeftLength, int mediaRightLength) { this.mediaLeftLength = mediaLeftLength; this.mediaRightLength = mediaRightLength; } // Implemented ============================================================ public int getMediaLeftIndex(int index) { return index; } public int getMediaRightIndex(int index) { return index; } public int getMediaLeftLength() { return mediaLeftLength; } public int getMediaRightLength() { return mediaRightLength; } }libsequence-java-1.0.2/src/main/java/de/regnis/q/sequence/media/QSequenceMediaIndexTransformer.java000066400000000000000000000012241177412531300333040ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.media; /** * @author Marc Strapetz */ public interface QSequenceMediaIndexTransformer { int getMediaLeftIndex(int index); int getMediaRightIndex(int index); int getMediaLeftLength(); int getMediaRightLength(); }libsequence-java-1.0.2/src/test/000077500000000000000000000000001177412531300165025ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/000077500000000000000000000000001177412531300174235ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/000077500000000000000000000000001177412531300200135ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/regnis/000077500000000000000000000000001177412531300213025ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/regnis/q/000077500000000000000000000000001177412531300215425ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/000077500000000000000000000000001177412531300233525ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceAllTests.java000066400000000000000000000022611177412531300275630ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import junit.framework.*; import de.regnis.q.sequence.line.*; /** * @author Marc Strapetz */ public class QSequenceAllTests { // Accessing ============================================================== public static Test suite() { final TestSuite suite = new TestSuite(de.regnis.q.sequence.QSequenceAllTests.class.getPackage().getName()); suite.addTestSuite(QSequenceLCSTest.class); suite.addTestSuite(QSequenceDifferenceCoreTest.class); suite.addTestSuite(QSequenceDifferenceAssemblyTest.class); suite.addTestSuite(QSequenceDifferenceBlockShifterTest.class); suite.addTestSuite(QSequenceLineReaderTest.class); suite.addTestSuite(QSequenceLineSimplifierTest.class); suite.addTestSuite(QSequenceLineMediaTest.class); return suite; } } libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceDifferenceAssemblyTest.java000066400000000000000000000125071177412531300324260ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import junit.framework.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceAssemblyTest extends TestCase { // Constants ============================================================== private static final int LINE_LENGTH = 3; private static final int ALPHABET_SIZE = 10; // Static ================================================================= public static String[] createLines(int lineCount, Random random) { final String[] lines = new String[lineCount]; for (int lineIndex = 0; lineIndex < lines.length; lineIndex++) { String line = createLine(random); lines[lineIndex] = line; } return lines; } public static String[] alterLines(String[] leftLines, double pMod, double pAddRemove, Random random) { final List rightLines = new ArrayList(); for (int leftIndex = 0; leftIndex < leftLines.length; leftIndex++) { if (random.nextDouble() < pMod) { rightLines.add(createLine(random)); continue; } else if (random.nextDouble() < pAddRemove) { continue; } rightLines.add(leftLines[leftIndex]); if (random.nextDouble() < pAddRemove) { rightLines.add(createLine(random)); } } return (String[])rightLines.toArray(new String[0]); } // Fields ================================================================= private Random random; // Implemented ============================================================ protected void setUp() throws Exception { super.setUp(); random = new Random(0); } // Accessing ============================================================== public void test() throws QSequenceException { testVariousLength(0.001, 0.001); testVariousLength(0.01, 0.05); testVariousLength(0.5, 0.5); } // Utils ================================================================== private void testVariousLength(double pMod, double pAddRemove) throws QSequenceException { for (int size = 10; size <= 1000; size += 50) { testOneLength(size, pMod, pAddRemove); } } private void testOneLength(int lineCount, double pMod, double pAddRemove) throws QSequenceException { final String[] left = createLines(lineCount, random); final String[] right = alterLines(left, pMod, pAddRemove, random); testDiff(left, right); } private boolean areLinesEqual(String[] diff, String[] right) { if (diff.length != right.length) { return false; } for (int index = 0; index < diff.length; index++) { if (!diff[index].equals(right[index])) { return false; } } return true; } private static String createLine(Random random) { String line = ""; for (int charIndex = 0; charIndex < LINE_LENGTH; charIndex++) { line += String.valueOf((char)('a' + (char)(Math.abs(random.nextInt()) % ALPHABET_SIZE))); } return line; } private void testDiff(String[] left, String[] right) throws QSequenceException { testDiff(left, right, Integer.MAX_VALUE); testDiff(left, right, (int)Math.sqrt(left.length + right.length)); testDiff(left, right, 2); } private void testDiff(String[] left, String[] right, int maximumSearchDepth) throws QSequenceException { final QSequenceTestMedia testMedia = QSequenceTestMedia.createStringMedia(left, right); testDiff(left, right, testMedia, new QSequenceMediaDummyIndexTransformer(testMedia.getLeftLength(), testMedia.getRightLength()), null, maximumSearchDepth); final QSequenceCachingMedia cachingMedia = new QSequenceCachingMedia(testMedia, new QSequenceDummyCanceller()); final QSequenceDiscardingMedia media = new QSequenceDiscardingMedia(cachingMedia, new QSequenceDiscardingMediaNoConfusionDectector(true), new QSequenceDummyCanceller()); testDiff(left, right, media, media, cachingMedia, maximumSearchDepth); } private void testDiff(String[] left, String[] right, QSequenceMedia media, QSequenceMediaIndexTransformer indexTransformer, QSequenceCachingMedia cachingMedia, int maximumSearchDepth) throws QSequenceException { final List blocks = new QSequenceDifference(media, indexTransformer, maximumSearchDepth).getBlocks(); if (cachingMedia != null) { new QSequenceDifferenceBlockShifter(cachingMedia, cachingMedia).shiftBlocks(blocks); } final List diffLines = new ArrayList(); int lastLeftTo = -1; for (int index = 0; index < blocks.size(); index++) { final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(index); for (int leftIndex = lastLeftTo + 1; leftIndex < block.getLeftFrom(); leftIndex++) { diffLines.add(left[leftIndex]); } lastLeftTo = block.getLeftTo(); for (int rightIndex = block.getRightFrom(); rightIndex <= block.getRightTo(); rightIndex++) { diffLines.add(right[rightIndex]); } } for (int leftIndex = lastLeftTo + 1; leftIndex < left.length; leftIndex++) { diffLines.add(left[leftIndex]); } final String[] diff = (String[])diffLines.toArray(new String[0]); if (!areLinesEqual(diff, right)) { fail(); } } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceDifferenceBlockShifterTest.java000066400000000000000000000057021177412531300332250ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import junit.framework.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceBlockShifterTest extends TestCase { // Accessing ============================================================== public void test() throws QSequenceException { test2("aa", "aaa", "aa", "aa-"); test2("xaa", "yaaa", "-aa", "--aa"); test2("ababab", "abababab", "ababab", "ababab--"); test2("xababab", "yabababab", "-ababab", "---ababab"); test2("public class PolygonExtractionTree implements QBBox2D {", "class PolygonExtractionTree implements QBBox2D {", "-------class PolygonExtractionTree implements QBBox2D {", "class PolygonExtractionTree implements QBBox2D {"); test2("abcde", "axcye", "a-c-e", "a-c-e"); test2("ab*#cd*#", "ab*#ef*#cd*#", "ab*#cd*#", "ab*#----cd*#"); } // Utils ================================================================== private void test2(String left, String right, String leftTest, String rightTest) throws QSequenceException { test1(left, right, leftTest, rightTest); test1(right, left, rightTest, leftTest); } private void test1(String left, String right, String leftTest, String rightTest) throws QSequenceException { final QSequenceTestMedia media = QSequenceTestMedia.createCharacterMedia(left, right); final QSequenceDifference difference = new QSequenceDifference(media, new QSequenceMediaDummyIndexTransformer(media.getLeftLength(), media.getRightLength())); final List blocks = difference.getBlocks(); final QSequenceDifferenceBlockShifter blockShifter = new QSequenceDifferenceBlockShifter(media, media); blockShifter.shiftBlocks(blocks); final StringBuffer leftBuffer = new StringBuffer(left); final StringBuffer rightBuffer = new StringBuffer(right); for (int index = 0; index < blocks.size(); index++) { final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(index); final int leftFrom = block.getLeftFrom(); final int leftTo = block.getLeftTo(); if (leftFrom <= leftTo) { leftBuffer.replace(leftFrom, leftTo + 1, QSequenceDifferenceCoreTest.fillWithChar("", leftTo - leftFrom + 1, '-')); } final int rightFrom = block.getRightFrom(); final int rightTo = block.getRightTo(); if (rightFrom <= rightTo) { rightBuffer.replace(rightFrom, rightTo + 1, QSequenceDifferenceCoreTest.fillWithChar("", rightTo - rightFrom + 1, '-')); } } assertEquals(leftTest, leftBuffer.toString()); assertEquals(rightTest, rightBuffer.toString()); } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceDifferenceCoreTest.java000066400000000000000000000106471177412531300315420ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import junit.framework.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceDifferenceCoreTest extends TestCase { // Static ================================================================= public static String fillWithChar(String string, int totalLength, char chr) { if (string.length() == totalLength) { return string; } final StringBuffer buffer = new StringBuffer(totalLength); buffer.append(string); fillWithChar(buffer, totalLength, chr); return buffer.toString(); } public static String fillWithChar(String string, int totalLength, int startIndex, char chr) { if (string.length() == totalLength) { return string; } final StringBuffer buffer = new StringBuffer(totalLength); buffer.append(string); fillWithChar(buffer, totalLength, startIndex, chr); return buffer.toString(); } public static StringBuffer fillWithChar(StringBuffer buffer, int totalLength, char chr) { return fillWithChar(buffer, totalLength, -1, chr); } public static StringBuffer fillWithChar(StringBuffer buffer, int totalLength, int startIndex, char chr) { buffer.ensureCapacity(totalLength); if (startIndex >= 0 && startIndex < buffer.length()) { while (buffer.length() < totalLength) { buffer.insert(startIndex, chr); } } else { while (buffer.length() < totalLength) { buffer.append(chr); } } return buffer; } // Accessing ============================================================== public void test() throws QSequenceException { test1("abcabba", "cbabac", "--c-bba", "cb-ba-"); test1("abcccd", "accccd", "a-cccd", "accc-d"); test2("abbb", "abbbb", "abbb", "abbb-"); test2("abccd", "abccd", "abccd", "abccd"); test2("abccd*", "abccd", "abccd-", "abccd"); test2("*abccd", "abccd", "-abccd", "abccd"); test2("abc*cd", "abccd", "abc-cd", "abccd"); test2("abccd", "x", "-----", "-"); test2("abccd", "", "-----", ""); test2("", "", "", ""); test2("Howdy", "Rucola", "-o---", "---o--"); test2("*bc", "bc", "-bc", "bc"); // Special case, which results immediately in D = 1 test2("b*c", "bc", "b-c", "bc"); // Special case, which results immediately in D = 1 test2("bc*", "bc", "bc-", "bc"); // Special case, which results immediately in D = 1 test2("abc*defgh*i*", "a+bc+defg+h+i++", "abc-defgh-i-", "a-bc-defg-h-i--"); } // Utils ================================================================== private void test2(String left, String right, String leftTest, String rightTest) throws QSequenceException { test1(left, right, leftTest, rightTest); test1(right, left, rightTest, leftTest); } private void test1(String left, String right, String leftTest, String rightTest) throws QSequenceException { final QSequenceTestMedia media = QSequenceTestMedia.createCharacterMedia(left, right); final QSequenceIntMedia cachingMedia = new QSequenceCachingMedia(media, new QSequenceDummyCanceller()); final QSequenceDiscardingMedia discardingMedia = new QSequenceDiscardingMedia(cachingMedia, new QSequenceDiscardingMediaNoConfusionDectector(false), new QSequenceDummyCanceller()); final List blocks = new QSequenceDifference(discardingMedia, discardingMedia).getBlocks(); final StringBuffer leftBuffer = new StringBuffer(left); final StringBuffer rightBuffer = new StringBuffer(right); for (int index = 0; index < blocks.size(); index++) { final QSequenceDifferenceBlock block = (QSequenceDifferenceBlock)blocks.get(index); final int leftFrom = block.getLeftFrom(); final int leftTo = block.getLeftTo(); if (leftFrom <= leftTo) { leftBuffer.replace(leftFrom, leftTo + 1, fillWithChar("", leftTo - leftFrom + 1, '-')); } final int rightFrom = block.getRightFrom(); final int rightTo = block.getRightTo(); if (rightFrom <= rightTo) { rightBuffer.replace(rightFrom, rightTo + 1, fillWithChar("", rightTo - rightFrom + 1, '-')); } } assertEquals(leftTest, leftBuffer.toString()); assertEquals(rightTest, rightBuffer.toString()); } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceLCSTest.java000066400000000000000000000056021177412531300273130ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import java.util.*; import junit.framework.*; import de.regnis.q.sequence.core.*; /** * @author Marc Strapetz */ public class QSequenceLCSTest extends TestCase { // Accessing ============================================================== public void test() throws QSequenceException { test1("abcabba", "cbabac", "cbba"); test1("cbabac", "abcabba", "baba"); test2("abccd", "abccd", "abccd"); test2("ab*", "ab", "ab"); test2("*abccd", "abccd", "abccd"); test2("***abccd", "abccd", "abccd"); test2("abc*d", "abc+d", "abcd"); test2("abc*d", "abcd", "abcd"); test2("abc*d", "abc++d", "abcd"); test2("abc*d", "abc+++d", "abcd"); test2("abc*d", "ab+c++++d", "abcd"); test2("ab", "ccd", ""); test2("ab", "bccd", "b"); test2("******a*****b*****c*c***d", "abccd", "abccd"); test2("******a*****b*****c*c***d", "+a+b+c+c+d+", "abccd"); test2("a", "***a", "a"); test2("a", "****a", "a"); test2("a", "a****", "a"); test2("", "", ""); test2("a", "", ""); test2("aaaaaaaaa", "", ""); test2("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "a", "a"); test2("This is a small test with some minor variations.", "Thies ist a smal text with some minbr variation.", "This is a smal tet with some minr variation."); } // Utils ================================================================== private void test2(String left, String right, String lcs) throws QSequenceException { test1(left, right, lcs); test1(right, left, lcs); } private void test1(String left, String right, String lcs) throws QSequenceException { final QSequenceTestMedia media = QSequenceTestMedia.createCharacterMedia(left, right); final List commands = new QSequenceSimpleLCS(media).getCommands(); int lastLeft = -1; int lastRight = -1; final StringBuffer calculatedLcs = new StringBuffer(); for (Iterator it = commands.iterator(); it.hasNext();) { final QSequenceSimpleLCSCommand command = (QSequenceSimpleLCSCommand)it.next(); if (command.isLeft()) { assertTrue(lastLeft <= command.getFrom()); for (int index = command.getFrom(); index <= command.getTo(); index++) { calculatedLcs.append(media.getLeftLine(index)); } lastLeft = command.getTo(); } else { assertTrue(lastRight <= command.getFrom()); for (int index = command.getFrom(); index <= command.getTo(); index++) { calculatedLcs.append(media.getRightLine(index)); } lastRight = command.getTo(); } } assertEquals(lcs, calculatedLcs.toString()); } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/QSequenceTestMedia.java000066400000000000000000000053151177412531300277120ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence; import junit.framework.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceTestMedia implements QSequenceCachableMedia, QSequenceMediaComparer { // Static ================================================================= public static QSequenceTestMedia createStringMedia(String[] left, String[] right) { return new QSequenceTestMedia(left, right); } public static QSequenceTestMedia createCharacterMedia(String leftChars, String rightChars) { final String[] left = new String[leftChars.length()]; for (int index = 0; index < left.length; index++) { left[index] = String.valueOf(leftChars.charAt(index)); } final String[] right = new String[rightChars.length()]; for (int index = 0; index < right.length; index++) { right[index] = String.valueOf(rightChars.charAt(index)); } return new QSequenceTestMedia(left, right); } // Fields ================================================================= private final String[] left; private final String[] right; // Setup ================================================================== private QSequenceTestMedia(String[] left, String[] right) { this.left = left; this.right = right; } // Implemented ============================================================ public int getLeftLength() { return left.length; } public int getRightLength() { return right.length; } public Object getMediaLeftObject(int index) { return left[index]; } public Object getMediaRightObject(int index) { return right[index]; } public boolean equals(int leftIndex, int rightIndex) { Assert.assertTrue(0 <= leftIndex && leftIndex < left.length); Assert.assertTrue(0 <= rightIndex && rightIndex < right.length); return left[leftIndex].equals(right[rightIndex]); } public boolean equalsLeft(int left1, int left2) throws QSequenceCancelledException { return left[left1].equals(left[left2]); } public boolean equalsRight(int right1, int right2) throws QSequenceCancelledException { return right[right1].equals(right[right2]); } // Accessing ============================================================== public String getLeftLine(int index) { return left[index]; } public String getRightLine(int index) { return right[index]; } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/line/000077500000000000000000000000001177412531300243015ustar00rootroot00000000000000libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/line/QSequenceLineMediaTest.java000066400000000000000000000154621177412531300314550ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import java.util.*; import junit.framework.*; import de.regnis.q.sequence.*; import de.regnis.q.sequence.line.simplifier.*; import de.regnis.q.sequence.core.*; import de.regnis.q.sequence.media.*; /** * @author Marc Strapetz */ public class QSequenceLineMediaTest extends TestCase { // Fields ================================================================= private Random random; // Implemented ============================================================ protected void setUp() throws Exception { super.setUp(); random = new Random(0); } // Accessing ============================================================== public void testBasicMemoryVersusFileSystem() throws IOException, QSequenceException { test(new String[] {"a", "c", "b."}, new String[] {"a", "d", "b."}, new QSequenceLineDummySimplifier(), null); } public void testSimplifier() throws IOException, QSequenceException { final String[] left = new String[] {"equal", "number of ws only ", "all ws"}; final String[] right = new String[] {"equal", "number\tof ws only ", " allws "}; test(left, right, new QSequenceLineDummySimplifier(), Collections.singletonList(new QSequenceDifferenceBlock(1, 2, 1, 2))); test(left, right, new QSequenceLineWhiteSpaceReducingSimplifier(), Collections.singletonList(new QSequenceDifferenceBlock(2, 2, 2, 2))); test(left, right, new QSequenceLineWhiteSpaceSkippingSimplifier(), Collections.EMPTY_LIST); } public void testRandomMemoryVersusFileSystem() throws IOException, QSequenceException { for (int size = 1; size <= 50; size += 1) { testRandomStrings(size, 0.3, 0.1); } } // Utils ================================================================== private void testRandomStrings(int lineCount, double pMod, double pAddRemove) throws IOException, QSequenceException { final String[] left = QSequenceDifferenceAssemblyTest.createLines(lineCount, random); final String[] right = QSequenceDifferenceAssemblyTest.alterLines(left, pMod, pAddRemove, random); test(left, right, new QSequenceLineDummySimplifier(), null); } private void test(String[] left, String[] right, QSequenceLineSimplifier simplifier, List expectedBlocks) throws IOException, QSequenceException { final File leftFile = createTestFile(left, true); final File rightFile = createTestFile(right, false); try { final QSequenceLineResult memoryResult = createBlocksInMemory(leftFile, rightFile, simplifier); final QSequenceLineResult raFileResult1 = createRAFileBlocks(leftFile, rightFile, 16, 16, simplifier); final QSequenceLineResult raFileResult2 = createRAFileBlocks(leftFile, rightFile, 256, 16, simplifier); final QSequenceLineResult raFileResult3 = createRAFileBlocks(leftFile, rightFile, 256, 64, simplifier); final QSequenceLineResult raFileResult4 = createRAFileBlocks(leftFile, rightFile, 256, 256, simplifier); final QSequenceLineResult raFileResult5 = createRAFileBlocks(leftFile, rightFile, Integer.MAX_VALUE, 48, simplifier); try { if (expectedBlocks != null) { compareBlocks(expectedBlocks, memoryResult.getBlocks()); } compareBlocks(memoryResult.getBlocks(), raFileResult1.getBlocks()); compareBlocks(memoryResult.getBlocks(), raFileResult2.getBlocks()); compareBlocks(memoryResult.getBlocks(), raFileResult3.getBlocks()); compareBlocks(memoryResult.getBlocks(), raFileResult4.getBlocks()); compareBlocks(memoryResult.getBlocks(), raFileResult5.getBlocks()); } finally { memoryResult.close(); raFileResult1.close(); raFileResult2.close(); raFileResult3.close(); raFileResult4.close(); raFileResult5.close(); } } finally { leftFile.delete(); rightFile.delete(); } } private static QSequenceLineResult createBlocksInMemory(final File leftFile, final File rightFile, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { final FileInputStream left = new FileInputStream(leftFile); final FileInputStream right = new FileInputStream(rightFile); final QSequenceLineMemoryCache leftCache = QSequenceLineMemoryCache.read(left, simplifier); final QSequenceLineMemoryCache rightCache = QSequenceLineMemoryCache.read(right, simplifier); final QSequenceLineMedia lineMedia = new QSequenceLineMedia(leftCache, rightCache); final QSequenceCachingMedia cachingMedia = new QSequenceCachingMedia(lineMedia, new QSequenceDummyCanceller()); final List blocks = new QSequenceDifference(cachingMedia, new QSequenceMediaDummyIndexTransformer(cachingMedia)).getBlocks(); new QSequenceDifferenceBlockShifter(cachingMedia, cachingMedia).shiftBlocks(blocks); return new QSequenceLineResult(blocks, leftCache, rightCache); } private static QSequenceLineResult createRAFileBlocks(File leftFile, File rightFile, int maximumMemorySize, int fileSegmentSize, QSequenceLineSimplifier simplifier) throws IOException, QSequenceException { final RandomAccessFile leftRAFile = new RandomAccessFile(leftFile, "r"); final RandomAccessFile rightRAFile = new RandomAccessFile(rightFile, "r"); try { return QSequenceLineMedia.createBlocksInFilesystem(new QSequenceLineRAFileData(leftRAFile), new QSequenceLineRAFileData(rightRAFile), new QSequenceLineSystemTempDirectoryFactory(), 1.0, maximumMemorySize, fileSegmentSize, simplifier); } finally { leftRAFile.close(); rightRAFile.close(); } } private static void compareBlocks(List expected, List actual) { assertEquals(expected.size(), actual.size()); for (int index = 0; index < expected.size(); index++) { final QSequenceDifferenceBlock expectedBlock = (QSequenceDifferenceBlock)expected.get(index); final QSequenceDifferenceBlock actualBlock = (QSequenceDifferenceBlock)actual.get(index); assertEquals(expectedBlock.getLeftFrom(), actualBlock.getLeftFrom()); assertEquals(expectedBlock.getLeftTo(), actualBlock.getLeftTo()); assertEquals(expectedBlock.getRightFrom(), actualBlock.getRightFrom()); assertEquals(expectedBlock.getRightTo(), actualBlock.getRightTo()); } } private static File createTestFile(String[] content, boolean left) throws IOException { final File file = File.createTempFile("SequenceMediaTest", left ? "left" : "right"); file.delete(); final FileOutputStream stream = new FileOutputStream(file); for (int index = 0; index < content.length; index++) { stream.write(content[index].getBytes()); if (index < content.length - 1) { stream.write("\n".getBytes()); } } stream.close(); return file; } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/line/QSequenceLineReaderTest.java000066400000000000000000000044301177412531300316310ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import java.io.*; import junit.framework.*; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ public class QSequenceLineReaderTest extends TestCase { // Accessing ============================================================== public void test() throws IOException { test("A simple string.", 1); test("Two\nlines.", 2); test("Three\nli\nnes.", 3); test("\nLine\n", 2); test("Line\r\n\r", 2); test("Line\r\n\r\n", 2); test("Line\r\r", 2); test("Line\r\r ", 3); test("Line\n\r\r", 3); test("\n\n\n", 3); test("", 0); test("Line", 1); test("Line\n", 1); test("Line\r\n", 1); test("Line\n\r", 2); test("Line\n\r\r", 3); } // Utils ================================================================== private void test(String testString, int expectedLineCount) throws IOException { final byte[] bytes = testString.getBytes(); final QSequenceLineMemoryCache cache = new QSequenceLineMemoryCache(); final QSequenceLineReader reader = new QSequenceLineReader(4); reader.read(new ByteArrayInputStream(bytes), cache, new QSequenceLineDummySimplifier()); assertEquals(expectedLineCount, cache.getLineCount()); for (int index = 0; index < cache.getLineCount(); index++) { final QSequenceLine line = cache.getLine(index); if (index == 0) { assertEquals(0, line.getFrom()); } else if (index == cache.getLineCount() - 1) { assertEquals(bytes.length, line.getFrom() + line.getContentLength()); } else { final int expectedTo = (int)cache.getLine(index - 1).getFrom() + cache.getLine(index - 1).getContentLength(); assertEquals(expectedTo, line.getFrom()); } for (int byteIndex = (int)line.getFrom(); byteIndex < line.getFrom() + line.getContentLength(); byteIndex++) { assertEquals(bytes[byteIndex], line.getContentBytes()[byteIndex - (int)line.getFrom()]); } } } }libsequence-java-1.0.2/src/test/java/de/regnis/q/sequence/line/QSequenceLineSimplifierTest.java000066400000000000000000000037131177412531300325350ustar00rootroot00000000000000/* * ==================================================================== * Copyright (c) 2000-2008 SyntEvo GmbH, info@syntevo.com * All rights reserved. * * This software is licensed as described in the file SEQUENCE-LICENSE, * which you should have received as part of this distribution. Use is * subject to license terms. * ==================================================================== */ package de.regnis.q.sequence.line; import junit.framework.*; import de.regnis.q.sequence.line.simplifier.*; /** * @author Marc Strapetz */ public class QSequenceLineSimplifierTest extends TestCase { // Accessing ============================================================== public void testDummySimplifier() { final QSequenceLineSimplifier simplifier = new QSequenceLineDummySimplifier(); assertEquals(" nothing\tto simplify \n", new String(simplifier.simplify(" nothing\tto simplify \n".getBytes()))); } public void testSkippingSimplifier() { final QSequenceLineSimplifier simplifier = new QSequenceLineWhiteSpaceSkippingSimplifier(); assertEquals("muchtosimplify", new String(simplifier.simplify(" much to simplify ".getBytes()))); assertEquals("muchtosimplify\n", new String(simplifier.simplify(" much\tto simplify \n ".getBytes()))); } public void testReducingSimplifier() { final QSequenceLineSimplifier simplifier = new QSequenceLineWhiteSpaceReducingSimplifier(); assertEquals(" something to simplify ", new String(simplifier.simplify(" something\t to simplify \t ".getBytes()))); assertEquals(" something to simplify\n", new String(simplifier.simplify(" something\t to simplify\n".getBytes()))); } public void testEolSkippingSimplifier() { final QSequenceLineSimplifier simplifier = new QSequenceLineTeeSimplifier(new QSequenceLineWhiteSpaceReducingSimplifier(), new QSequenceLineEOLUnifyingSimplifier()); assertEquals(" something to simplify\n", new String(simplifier.simplify(" something\t to simplify\n\r".getBytes()))); } }