/* * Copyright 2015 MiLaboratory.com * * 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 com.milaboratory.core.sequence; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import gnu.trove.impl.Constants; import gnu.trove.map.hash.TIntObjectHashMap; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Registry of all alphabets. */ public final class Alphabets { private final static Map<String, Alphabet> alphabetsByName = new HashMap<>(); private final static TIntObjectHashMap<Alphabet> alphabetsById = new TIntObjectHashMap<>(Constants.DEFAULT_CAPACITY, Constants.DEFAULT_LOAD_FACTOR, Byte.MIN_VALUE); private Alphabets() { } /** * Register new alphabet * * @param alphabet alphabet */ public static void register(Alphabet alphabet) { if (alphabetsByName.put(alphabet.getAlphabetName(), alphabet) != null) throw new IllegalStateException("Alphabet with this name is already registered."); if (alphabetsById.put(alphabet.getId(), alphabet) != null) throw new IllegalStateException("Alphabet with this id is already registered."); } static { register(NucleotideAlphabet.INSTANCE); register(AminoAcidAlphabet.INSTANCE); } /** * Returns instance of {@code Alphabet} from its string name. * * @param name string name of alphabet * @return instance of {@code Alphabet} from its string name */ public static Alphabet getByName(String name) { return alphabetsByName.get(name); } /** * Searches for instance of {@code Alphabet} using first letter of it's name * * @param letter first letter of alphabet's name * @return instance of {@code Alphabet} */ public static Alphabet getByFirstLetterOfName(char letter) { letter = Character.toLowerCase(letter); for (Alphabet alphabet : alphabetsByName.values()) if (alphabet.getAlphabetName().charAt(0) == letter) return alphabet; throw new IllegalArgumentException("No alphabet starting with letter: " + letter); } /** * Returns instance of {@code Alphabet} from its byte id. * * @param id byte id of alphabet * @return instance of {@code Alphabet} from its byte id */ public static Alphabet getById(byte id) { return alphabetsById.get(id); } /** * Returns unmodifiable collection of all registered alphabets. * * @return unmodifiable collection of all registered alphabets */ public static Collection<Alphabet> getAll() { return Collections.unmodifiableCollection(alphabetsByName.values()); } /* JSON serializers / deserializers */ public static final class Deserializer extends JsonDeserializer<Alphabet> { @Override public Alphabet deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { return Alphabets.getByName(jp.readValueAs(String.class)); } @Override public Alphabet getEmptyValue(DeserializationContext context) { return NucleotideAlphabet.INSTANCE; } @Override public Alphabet getNullValue(DeserializationContext context) { return NucleotideAlphabet.INSTANCE; } } public static final class Serializer extends JsonSerializer<Alphabet> { @Override public void serialize(Alphabet value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeString(value.getAlphabetName()); } } }