All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datavec.api.writable.WritableFactory Maven / Gradle / Ivy

There is a newer version: 1.0.0-M2.1
Show newest version
/*-
 *  * Copyright 2016 Skymind, Inc.
 *  *
 *  *    Licensed under the Apache License, Version 2.0 (the "License");
 *  *    you may not use this file except in compliance with the License.
 *  *    You may obtain a copy of the License at
 *  *
 *  *        http://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  *    Unless required by applicable law or agreed to in writing, software
 *  *    distributed under the License is distributed on an "AS IS" BASIS,
 *  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  *    See the License for the specific language governing permissions and
 *  *    limitations under the License.
 */

package org.datavec.api.writable;

import lombok.NonNull;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Factory class for creating and saving writable objects to/from DataInput and DataOutput
 *
 * @author Alex Black
 */
public class WritableFactory {

    private static WritableFactory INSTANCE = new WritableFactory();

    private Map> map = new ConcurrentHashMap<>();
    private Map> constructorMap = new ConcurrentHashMap<>();

    private WritableFactory() {
        for (WritableType wt : WritableType.values()) {
            if (wt.isCoreWritable()) {
                registerWritableType((short) wt.ordinal(), wt.getWritableClass());
            }
        }
    }

    /**
     * @return Singleton WritableFactory instance
     */
    public static WritableFactory getInstance() {
        return INSTANCE;
    }

    /**
     * Register a writable class with a specific key (as a short). Note that key values must be unique for each type of
     * Writable, as they are used as type information in certain types of serialisation. Consequently, an exception will
     * be thrown If the key value is not unique or is already assigned.
* Note that in general, this method needs to only be used for custom Writable types; Care should be taken to ensure * that the given key does not change once assigned. * * @param writableTypeKey Key for the Writable * @param writableClass Class for the given key. Must have a no-arg constructor */ public void registerWritableType(short writableTypeKey, @NonNull Class writableClass) { if (map.containsKey(writableTypeKey)) { throw new UnsupportedOperationException("Key " + writableTypeKey + " is already registered to type " + map.get(writableTypeKey) + " and cannot be registered to " + writableClass); } Constructor c; try { c = writableClass.getDeclaredConstructor(); } catch (NoSuchMethodException e) { throw new RuntimeException("Cannot find no-arg constructor for class " + writableClass); } map.put(writableTypeKey, writableClass); constructorMap.put(writableTypeKey, c); } /** * Create a new writable instance (using reflection) given the specified key * * @param writableTypeKey Key to create a new writable instance for * @return A new (empty/default) Writable instance */ public Writable newWritable(short writableTypeKey) { Constructor c = constructorMap.get(writableTypeKey); if (c == null) { throw new IllegalStateException("Unknown writable key: " + writableTypeKey); } try { return c.newInstance(); } catch (Exception e) { throw new RuntimeException("Could not create new Writable instance"); } } /** * A convenience method for writing a given Writable object to a DataOutput. The key is 1st written (a single short) * followed by the value from writable. * * @param w Writable value * @param dataOutput DataOutput to write both key and value to * @throws IOException If an error occurs during writing to the DataOutput */ public void writeWithType(Writable w, DataOutput dataOutput) throws IOException { w.writeType(dataOutput); w.write(dataOutput); } /** * Read a Writable From the DataInput, where the Writable was previously written using {@link #writeWithType(Writable, DataOutput)} * * @param dataInput DataInput to read the Writable from * @return Writable from the DataInput * @throws IOException In an error occurs during reading */ public Writable readWithType(DataInput dataInput) throws IOException { Writable w = newWritable(dataInput.readShort()); w.readFields(dataInput); return w; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy