package com.proverby.api;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.proverby.api.ParseStatus;
import com.proverby.api.Proverb;
import com.proverby.api.Query;
public class EarthProverbsApi
{
private volatile List<Proverb> proverbs;
private volatile List<Country> countries;
private volatile List<String> tags;
private volatile List<String> regions;
private volatile Set<EarthProverbsListener> proverbListeners;
private volatile Set<EarthProverbsListener> countryListeners;
private volatile Set<EarthProverbsListener> tagListeners;
private volatile Set<EarthProverbsListener> regionListeners;
private final Lock lock = new ReentrantLock();
private static EarthProverbsApi instance;
private EarthProverbsApi()
{
proverbs = new ArrayList<Proverb>();
countries = new ArrayList<Country>();
tags = new ArrayList<String>();
regions = new ArrayList<String>();
proverbListeners = new HashSet<EarthProverbsListener>();
countryListeners = new HashSet<EarthProverbsListener>();
tagListeners = new HashSet<EarthProverbsListener>();
regionListeners = new HashSet<EarthProverbsListener>();
}
public static EarthProverbsApi getInstance()
{
if ( instance == null )
synchronized (instance)
{
if ( instance == null )
instance = new EarthProverbsApi();
}
return instance;
}
public void attachProverbListener(EarthProverbsListener listener)
{
proverbListeners.add(listener);
}
public void attachCountryListener(EarthProverbsListener listener)
{
countryListeners.add(listener);
}
public void attachTagListener(EarthProverbsListener listener)
{
tagListeners.add(listener);
}
public void attachRegionListener(EarthProverbsListener listener)
{
regionListeners.add(listener);
}
public void removeProverbListener(EarthProverbsListener listener)
{
try
{
lock.lock();
if (proverbListeners.contains(listener))
proverbListeners.remove(listener);
}
finally
{
lock.unlock();
}
}
public void removeCountryListener(EarthProverbsListener listener)
{
try
{
lock.lock();
if (countryListeners.contains(listener))
countryListeners.remove(listener);
}
finally
{
lock.unlock();
}
}
public void removeTagListener(EarthProverbsListener listener)
{
try
{
lock.lock();
if (tagListeners.contains(listener))
tagListeners.remove(listener);
}
finally
{
lock.unlock();
}
}
public void removeRegionListener(EarthProverbsListener listener)
{
try
{
lock.lock();
if (regionListeners.contains(listener))
regionListeners.remove(listener);
}
finally
{
lock.unlock();
}
}
public void listProverbs(Query query)
{
ParseStatus status = ParseStatus.LOADING;
Iterator<EarthProverbsListener> iterator = proverbListeners.iterator();
while (iterator.hasNext())
{
iterator.next().loading();
}
ObjectMapper mapper = new ObjectMapper();
try
{
URL url = query.getURL();
lock.lock();
proverbs = mapper.readValue(url, new TypeReference<List<JsonProverb>>() {
});
status = ParseStatus.SUCCESS;
}
catch (MalformedURLException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
catch (JsonParseException e)
{
status = ParseStatus.TRY_AGAIN;
}
catch (JsonMappingException e)
{
status = ParseStatus.JSON_ERROR;
}
catch (IOException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
finally
{
lock.unlock();
}
iterator = proverbListeners.iterator();
while (iterator.hasNext())
{
iterator.next().finished(status);
}
}
public void listCountries(Query query)
{
ParseStatus status = ParseStatus.LOADING;
Iterator<EarthProverbsListener> iterator = countryListeners.iterator();
while (iterator.hasNext())
{
iterator.next().loading();
}
ObjectMapper mapper = new ObjectMapper();
try
{
URL url = query.getURL();
lock.lock();
countries = mapper.readValue(url, new TypeReference<List<JsonCountry>>() {
});
status = ParseStatus.SUCCESS;
}
catch (MalformedURLException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
catch (JsonParseException e)
{
status = ParseStatus.TRY_AGAIN;
}
catch (JsonMappingException e)
{
status = ParseStatus.JSON_ERROR;
}
catch (IOException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
finally
{
lock.unlock();
}
iterator = countryListeners.iterator();
while (iterator.hasNext())
{
iterator.next().finished(status);
}
}
public void listTags()
{
ParseStatus status = ParseStatus.LOADING;
Query query = Query.createTagListQuery();
Iterator<EarthProverbsListener> iterator = tagListeners.iterator();
while (iterator.hasNext())
{
iterator.next().loading();
}
ObjectMapper mapper = new ObjectMapper();
try
{
URL url = query.getURL();
lock.lock();
tags = mapper.readValue(url, new TypeReference<List<String>>() {
});
status = ParseStatus.SUCCESS;
}
catch (MalformedURLException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
catch (JsonParseException e)
{
status = ParseStatus.TRY_AGAIN;
}
catch (JsonMappingException e)
{
status = ParseStatus.JSON_ERROR;
}
catch (IOException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
finally
{
lock.unlock();
}
iterator = tagListeners.iterator();
while (iterator.hasNext())
{
iterator.next().finished(status);
}
}
public void listRegions()
{
ParseStatus status = ParseStatus.LOADING;
Query query = Query.createRegionListQuery();
Iterator<EarthProverbsListener> iterator = regionListeners.iterator();
while (iterator.hasNext())
{
iterator.next().loading();
}
ObjectMapper mapper = new ObjectMapper();
try
{
URL url = query.getURL();
lock.lock();
regions = mapper.readValue(url, new TypeReference<List<String>>() {
});
status = ParseStatus.SUCCESS;
}
catch (MalformedURLException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
catch (JsonParseException e)
{
status = ParseStatus.TRY_AGAIN;
}
catch (JsonMappingException e)
{
status = ParseStatus.JSON_ERROR;
}
catch (IOException e)
{
status = ParseStatus.NETWORK_FAILURE;
}
finally
{
lock.unlock();
}
iterator = regionListeners.iterator();
while (iterator.hasNext())
{
iterator.next().finished(status);
}
}
public List<Country> getCountries()
{
return countries;
}
public List<Proverb> getProverbs()
{
return proverbs;
}
public List<String> getTags()
{
return tags;
}
public List<String> getRegions()
{
return regions;
}
}