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

it.tidalwave.bluebill.taxonomy.birds.itis.ItisCodeMap Maven / Gradle / Ivy

There is a newer version: 1.0.18
Show newest version
/***********************************************************************************************************************
 *
 * blueBill Mobile - open source birdwatching
 * ==========================================
 *
 * Copyright (C) 2009, 2010 by Tidalwave s.a.s. (http://www.tidalwave.it)
 * http://bluebill.tidalwave.it/mobile/
 *
 ***********************************************************************************************************************
 *
 * 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.
 *
 ***********************************************************************************************************************
 *
 * $Id: ItisCodeMap.java,v 2bd379506d64 2010/07/23 21:17:08 fabrizio $
 *
 **********************************************************************************************************************/
package it.tidalwave.bluebill.taxonomy.birds.itis;

import it.tidalwave.util.NotFoundException;
import it.tidalwave.util.logging.Logger;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/***********************************************************************************************************************
 *
 * @author  Fabrizio Giudici
 * @version $Id: $
 *
 **********************************************************************************************************************/
public class ItisCodeMap
  {
    private static final String CLASS = ItisCodeMap.class.getName();
    private static final Logger logger = Logger.getLogger(CLASS);

    private static final String TYPE_CLASS = "60";
    private static final String TYPE_ORDER = "100";
    private static final String TYPE_FAMILY = "140";
    private static final String TYPE_GENUS = "180";
    private static final String TYPE_SPECIES = "220";
    private static final String TYPE_SUBSPECIES = "230";

    private final Map itemMapByCode = new HashMap();

    private final Map stringMapByCode = new HashMap();

    private final SortedMap codeMapByPath = new TreeMap();

//    private final Clements2008ToItisTranslator itisTranslator = new Clements2008ToItisTranslator();

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    private static class Item
      {
        @Nonnull
        public final String name;

        @Nullable
        public final Item parent;

        public Item (final @Nonnull String name, final @Nullable Item parent)
          {
            this.name = name;
            this.parent = parent;
          }

        @Nonnull
        public String getPath()
          {
            return (parent != null) ? parent.getPath() + "/" + name : name;
          }

        @Override
        public boolean equals (final @Nullable Object objext)
          {
            if (objext == null)
              {
                return false;
              }

            if (getClass() != objext.getClass())
              {
                return false;
              }
            final Item other = (Item)objext;

            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name))
              {
                return false;
              }

            if (this.parent != other.parent && (this.parent == null || !this.parent.equals(other.parent)))
              {
                return false;
              }

            return true;
          }

        @Override
        public int hashCode()
          {
            int hash = 5;
            hash = 71 * hash + (this.name != null ? this.name.hashCode() : 0);
            hash = 71 * hash + (this.parent != null ? this.parent.hashCode() : 0);
            return hash;
          }

        @Override @Nonnull
        public String toString()
          {
            return name;
          }
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void initialize()
      throws IOException
      {
        final InputStream is = getClass().getResourceAsStream("126179.bin");
        run(is);
        is.close();
//        itisTranslator.loadConfiguration();
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void run (final @Nonnull File file)
      throws IOException
      {
        final FileInputStream is = new FileInputStream(file);
        run(is);
        is.close();
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    public void run (final @Nonnull InputStream is)
      throws IOException
      {
        final BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

        for (;;)
          {
            final String s = br.readLine();

            if (s == null)
              {
                break;
              }

            final String[] split = s.split("\\|");
//            [TU]|174371||Aves||||||||valid||TWG standards met|complete|2001|0|1996-06-13 14:51:08|331030||0||0|5|60|No|
            final String what = split[0];
            final String code = split[1];

            if (what.equals("[TU]"))
              {
                final String valid = split[11];
                
                if (valid.equals("valid"))
                  {
                    stringMapByCode.put(code, s);
                  }
              }
          }

        br.close();

        while (!stringMapByCode.isEmpty())
          {
            process(stringMapByCode.values().iterator().next());
          }
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public String findCodeByPath (final @Nonnull String path)
      throws NotFoundException
      {
        final String translatedPath = path;
//        final String translatedPath = itisTranslator.translated(path);

        if (!translatedPath.equals(path))
          {
            logger.finer("ITIS %s ---> %s",  path, translatedPath);
          }

        try
          {
            return findCodeByRawPath( translatedPath);
          }
        catch (NotFoundException e)
          {
            final String[] split = translatedPath.split("/");

            for (int i = split.length - 1; i > 1; i--)
              {
                if (Character.isUpperCase(split[i].charAt(0)))
                  {
                    if (i == split.length - 2)
                      {
                        return findCodeBySpecies(split[i], split[i+1]);
                      }
                    else if (i == split.length - 3)
                      {
                        return findCodeBySubspecies(split[i], split[i+1], split[i+2]);
                      }
                  }
              }

            throw new NotFoundException(translatedPath);
          }
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    protected String findCodeByRawPath (final @Nonnull String path)
      throws NotFoundException
      {
        return NotFoundException.throwWhenNull(codeMapByPath.get(path), "No code for %s", path);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public String findCodeBySpecies (final @Nonnull String genusName, final @Nonnull String speciesName)
      throws NotFoundException
      {
        final String genusPath = "/" + genusName + "/" + speciesName;

        for (final Entry entry : codeMapByPath.entrySet())
          {
            if (entry.getKey().endsWith(genusPath))
              {
                return entry.getValue();
              }
          }

        throw new NotFoundException("No ITIS code for " + genusPath);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public String findCodeBySubspecies (final @Nonnull String genusName,
                                        final @Nonnull String speciesName,
                                        final @Nonnull String subSpeciesName)
      throws NotFoundException
      {
        final String genusPath = "/" + genusName + "/" + speciesName + "/" + subSpeciesName;

        for (final Entry entry : codeMapByPath.entrySet())
          {
            if (entry.getKey().endsWith(genusPath))
              {
                return entry.getValue();
              }
          }

        throw new NotFoundException("No ITIS code for " + genusPath);
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    @Nonnull
    public SortedSet getPaths()
      {
        return new TreeSet(codeMapByPath.keySet());
      }

    /*******************************************************************************************************************
     *
     *
     ******************************************************************************************************************/
    private void process (final @Nonnull String s)
      {
        final String[] split = s.split("\\|");
        final String code = split[1];
        final String name1 = split[3];
        final String name2 = split[5];
        final String name3 = split[7];
        final String standards = split[13];
        final String complete = split[14];
        final String year = split[15];
        final String dateTime = split[17];
        final String parentCode = split[18];
        final String type = split[24];

        String name = name1;


        if (TYPE_SPECIES.equals(type))
          {
            name = name2;
          }
        else if (TYPE_SUBSPECIES.equals(type))
          {
            name = name3;
          }

        if (!itemMapByCode.containsKey(parentCode) && !name.equals("Aves"))
          {
            process(stringMapByCode.get(parentCode));
          }

        final Item parentItem = itemMapByCode.get(parentCode);
        final Item item = new Item(name, parentItem);

        itemMapByCode.put(code, item);

        if ((parentItem == null) && !name.equals("Aves"))
          {
            throw new RuntimeException("Can't find parent: " + parentCode);
          }

        stringMapByCode.remove(code);
        codeMapByPath.put("/Animalia/Chordata/" + item.getPath().replaceAll("/[A-Z][^/]*nae/", "/"), code);
//        codeMapByPath.put("/Animalia/Chordata/" + item.getPath(), code);
      }
  }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy