Commit 06c1a703 authored by David Novak's avatar David Novak
Browse files

minor convenience updates; float vector's method toString now prints the raw...

minor convenience updates; float vector's method toString now prints the raw data (needed for GetObjectOperation#answer called by CoreApplication)
parent 12b03ac8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@

    <groupId>messif</groupId>
    <artifactId>messif</artifactId>
    <version>2.3.8-DEVEL</version>
    <version>2.3.9-DEVEL</version>
    <packaging>jar</packaging>
    <url>http://disa.fi.muni.cz/trac/messif/</url>

+26 −30
Original line number Diff line number Diff line
@@ -16,25 +16,6 @@
 */
package messif.buckets.storage.impl;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import messif.buckets.BucketStorageException;
import messif.buckets.StorageFailureException;
import messif.buckets.index.IndexComparator;
@@ -55,6 +36,21 @@ import messif.utility.ExtendedDatabaseConnection;
import messif.utility.ModifiableParametric;
import messif.utility.Parametric;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.*;

/**
 * Database-based storage.
 * The objects in this storage are stored in a relational database that
@@ -90,14 +86,14 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
     *
     * @param <T> the type of the instance that is stored/read from the database column
     */
    public static interface ColumnConvertor<T> extends Serializable {
    public interface ColumnConvertor<T> extends Serializable {
        /**
         * Returns a value that can be stored in a database column for the given instance.
         * @param instance the object instance from which to create a database value
         * @return a database value
         * @throws BucketStorageException if the value cannot be converted
         */
        public Object convertToColumnValue(T instance) throws BucketStorageException;
        Object convertToColumnValue(T instance) throws BucketStorageException;

        /**
         * Returns whether the {@link #convertToColumnValue(java.lang.Object) convertToColumnValue}
@@ -106,7 +102,7 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
         *          or should be skipped (<tt>false</tt>) when the object is
         *          stored into the storage
         */
        public boolean isConvertToColumnUsed();
        boolean isConvertToColumnUsed();

        /**
         * Returns an instance of object from the database column value.
@@ -118,7 +114,7 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
         * @return an instance created from the column value
         * @throws BucketStorageException if the value cannot be converted
         */
        public T convertFromColumnValue(T value, Object column) throws BucketStorageException;
        T convertFromColumnValue(T value, Object column) throws BucketStorageException;

        /**
         * Returns whether the {@link #convertFromColumnValue convertFromColumnValue}
@@ -127,7 +123,7 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
         *          or should be skipped (<tt>false</tt>) when the object is
         *          retrieved from the storage
         */
        public boolean isConvertFromColumnUsed();
        boolean isConvertFromColumnUsed();
    }

    /**
@@ -138,7 +134,7 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
     * @param <K> the type of the key arguments of the comparison
     * @param <T> the type of the instance that is stored/read from the database column
     */
    public static interface SearchableColumnConvertor<K, T> extends ColumnConvertor<T> {
    public interface SearchableColumnConvertor<K, T> extends ColumnConvertor<T> {
        /**
         * Returns <tt>true</tt> if the instance created by this convertor is compatible
         * with the given index comparator. If <tt>true</tt> is returned, the column
@@ -146,14 +142,14 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
         * @param indexComparator the index comparator that is checked for compatibility
         * @return <tt>true</tt> if this column convertor works with compatible instances
         */
        public boolean isColumnCompatible(IndexComparator<?, ? super T> indexComparator);
        boolean isColumnCompatible(IndexComparator<?, ? super T> indexComparator);

        /**
         * Returns a column value that can be used to search inside the database.
         * @param key the key from which to create a database value
         * @return a database value
         */
        public Object convertKeyToColumnValue(K key);
        Object convertKeyToColumnValue(K key);
    }


@@ -1301,9 +1297,9 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
    }

    /**
     * Column convertor that stores/restores instances supported directly by the database.
     * Column converter that stores/restores instances supported directly by the database.
     * For example, numbers can be accessed as {@link Integer}s or {@link Double}s, BLOBs as byte[] arrays, etc.
     * Note that this convertor states a compatibility with {@link LocalAbstractObjectOrder#trivialObjectComparator}
     * Note that this converter states a compatibility with {@link LocalAbstractObjectOrder#trivialObjectComparator}
     * since practically all database types are inherently {@link Comparable}.
     */
    public static final ColumnConvertor<Object> trivialColumnConvertor = new SearchableColumnConvertor<Object, Object>() {
@@ -1330,7 +1326,7 @@ public class DatabaseStorage<T> extends ExtendedDatabaseConnection implements In
        }

        @Override
        public boolean isColumnCompatible(IndexComparator<?, Object> indexComparator) {
        public boolean isColumnCompatible(IndexComparator<?, ? super Object> indexComparator) {
            return indexComparator != null && indexComparator.equals(LocalAbstractObjectOrder.trivialObjectComparator);
        }

+47 −14
Original line number Diff line number Diff line
@@ -16,22 +16,18 @@
 */
package messif.objects.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import messif.objects.DistanceFunction;
import messif.objects.LocalAbstractObject;
import messif.objects.MetaObject;
import messif.objects.keys.AbstractObjectKey;
import messif.utility.ArrayMap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.*;

/**
 * This is an implementation of the {@link MetaObject} which stores data in fixed {@link ArrayMap}.
 * @author David Novak, Masaryk University, Brno, Czech Republic, david.novak@fi.muni.cz
@@ -162,6 +158,35 @@ public class MetaObjectFixedMap extends MetaObject implements Serializable {
        }
    }

    /**
     * Create this meta object by (shallow) copying of data in given map.
     * @param copyObject meta object to copy all object from (and also locator)
     * @param keysToCopy set of keys to copy from the object
     */
    public MetaObjectFixedMap(MetaObject copyObject, Set<String> keysToCopy) {
        super(copyObject.getLocatorURI());

        String [] keys = new String [copyObject.getObjectCount()];
        LocalAbstractObject [] values = new LocalAbstractObject [copyObject.getObjectCount()];
        int nFields = 0;
        for (Map.Entry<String, ? extends LocalAbstractObject> field : copyObject.getObjectMap().entrySet()) {
            if (keysToCopy.contains(field.getKey())) {
                keys[nFields] = field.getKey();
                values[nFields] = field.getValue();
                nFields ++;
            }
        }
        if (nFields < keys.length) {
            keys = Arrays.copyOf(keys, nFields);
            values = Arrays.copyOf(values, nFields);
        }

        this.objects = new ArrayMap(keys, values, false);
        if (copyObject instanceof MetaObjectFixedMap) {
            this.distance = ((MetaObjectFixedMap) copyObject).distance;
        }
    }

    
    // *************       Contructors from the text representation of MESSIF 2.X     ********** //
    
@@ -236,6 +261,10 @@ public class MetaObjectFixedMap extends MetaObject implements Serializable {
        return distance.getDistance(this, (MetaObject) obj);
    }

    @Override
    public Map<String, ? extends LocalAbstractObject> getObjectMap() {
        return objects;
    }

    //****************** Text stream I/O ******************//

@@ -246,6 +275,10 @@ public class MetaObjectFixedMap extends MetaObject implements Serializable {

    @Override
    public String toString() {
        return objects.toString();
        return new StringBuilder().append('"').append(getLocatorURI()).append('"').append(": ").append(objects.toString()).toString();
    }

    public String toJSONString() {
        return new StringBuilder("{\"id\": \"").append(getLocatorURI()).append(objects.isEmpty() ? "\"" : "\", ").append(objects.toString().substring(1)).toString();
    }
}
+12 −10
Original line number Diff line number Diff line
@@ -16,12 +16,6 @@
 */
package messif.objects.impl;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;
import messif.objects.LocalAbstractObject;
import messif.objects.nio.BinaryInput;
import messif.objects.nio.BinaryOutput;
@@ -29,6 +23,13 @@ import messif.objects.nio.BinarySerializable;
import messif.objects.nio.BinarySerializator;
import messif.objects.util.AbstractObjectIterator;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;


/**
 * This object uses static array of floats as its data content.
@@ -418,10 +419,11 @@ public abstract class ObjectFloatVector extends LocalAbstractObject implements B
     */
    @Override
    public String toString() {
        if (getLocatorURI() != null) {
            return super.toString();
        }
        StringBuffer rtv = new StringBuffer(super.toString()).append(" [");
//        if (getLocatorURI() != null) {
//            return super.toString();
//        }
//        StringBuffer rtv = new StringBuffer(super.toString()).append(" [");
        StringBuffer rtv = new StringBuffer("[");

        for (int i = 0; i < this.data.length; i++) {
            if (i > 0) rtv.append(", ");
+45 −7
Original line number Diff line number Diff line
@@ -24,11 +24,13 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
import messif.objects.AbstractObject;
import messif.objects.LocalAbstractObject;
import messif.objects.MetaObject;
import messif.objects.impl.MetaObjectFixedMap;
import messif.operations.AbstractOperation;
import messif.operations.OperationErrorCode;
import messif.utility.ErrorCode;
@@ -56,6 +58,16 @@ public class PrintAllObjectsOperation extends AbstractOperation {
    /** Name of the file to print the result to. */
    private final String outputFileName;

    /**
     * If not null and if the printed objects are {@link messif.objects.MetaObject} then this operation prints
     *  only the fields specified in this array.
     */
    private final Set<String> fieldsToPrint;

    /**
     * If true, the operation does not use {@link LocalAbstractObject#write(OutputStream)} but {@link Object#toString()}.
     */
    private final boolean printAsJSON;

    // ***************   Output attribute     ********************* //
    
@@ -69,10 +81,11 @@ public class PrintAllObjectsOperation extends AbstractOperation {
     * Creates a new instance of PrintAllObjectsOperation.
     * @param printJustIDs if true, just line separated object IDs are printed
     * @param outputFileName name of text file to print the objects to; if ends with ".gz", the data is compressed
     * @param fieldsToPrint list of MetaObject fields to print
     * @throws java.io.IOException if the file cannot be created or written to
     */
    @AbstractOperation.OperationConstructor({"t/f print just IDs", "output file name"})
    public PrintAllObjectsOperation(boolean printJustIDs, String outputFileName) throws IOException {
    @AbstractOperation.OperationConstructor({"t/f print just IDs", "output file name", "array of fields to print"})
    public PrintAllObjectsOperation(boolean printJustIDs, String outputFileName, String [] fieldsToPrint, boolean printAsJSON) throws IOException {
        super();
        this.printJustIDs = printJustIDs;
        this.outputFileName = outputFileName;
@@ -80,6 +93,19 @@ public class PrintAllObjectsOperation extends AbstractOperation {
        if (outputFileName.endsWith(".gz")) {
            this.output = new GZIPOutputStream(output);
        }
        this.fieldsToPrint = (fieldsToPrint == null) ? null : new HashSet<String>(Arrays.asList(fieldsToPrint));
        this.printAsJSON = printAsJSON;
    }

    /**
     * Creates a new instance of PrintAllObjectsOperation.
     * @param printJustIDs if true, just line separated object IDs are printed
     * @param outputFileName name of text file to print the objects to; if ends with ".gz", the data is compressed
     * @throws java.io.IOException if the file cannot be created or written to
     */
    @AbstractOperation.OperationConstructor({"t/f print just IDs", "output file name"})
    public PrintAllObjectsOperation(boolean printJustIDs, String outputFileName) throws IOException {
        this(printJustIDs, outputFileName, null, false);
    }

    /**
@@ -106,8 +132,12 @@ public class PrintAllObjectsOperation extends AbstractOperation {
            return printJustIDs;
        case 1:
            return outputFileName;
        case 2:
            return fieldsToPrint;
        case 3:
            return printAsJSON;
        default:
            throw new IndexOutOfBoundsException("GetAllObjectsQueryOperation has only two arguments");
            throw new IndexOutOfBoundsException("GetAllObjectsQueryOperation has only " + getArgumentCount() + "  arguments");
        }
    }

@@ -117,7 +147,7 @@ public class PrintAllObjectsOperation extends AbstractOperation {
     */
    @Override
    public int getArgumentCount() {
        return 2;
        return 4;
    }


@@ -132,10 +162,18 @@ public class PrintAllObjectsOperation extends AbstractOperation {
        if (printJustIDs || (!(object instanceof LocalAbstractObject))) {
            output.write(object.getLocatorURI().getBytes());
            output.write('\n');
        } else {
            if (fieldsToPrint != null && object instanceof MetaObject) {
                final MetaObjectFixedMap prunedObject = new MetaObjectFixedMap(((MetaObject) object), fieldsToPrint);
                if (printAsJSON) {
                    output.write(prunedObject.toJSONString().getBytes());
                    output.write('\n');
                }
            } else {
                ((LocalAbstractObject) object).write(output);
            }
        }
    }
    
    
    /**
Loading