it.tidalwave.bluebill.taxonomy.birds.itis.ItisCodeMap Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* 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);
}
}