/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2017 Dennis Sheirer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/
package alias;
import alias.id.AliasID;
import alias.id.WildcardID;
import alias.id.esn.Esn;
import alias.id.fleetsync.FleetsyncID;
import alias.id.lojack.LoJackFunctionAndID;
import alias.id.mdc.MDC1200ID;
import alias.id.mobileID.Min;
import alias.id.mpt1327.MPT1327ID;
import alias.id.siteID.SiteID;
import alias.id.status.StatusID;
import alias.id.talkgroup.TalkgroupID;
import alias.id.uniqueID.UniqueID;
import module.decode.lj1200.LJ1200Message.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sample.Listener;
import javax.xml.bind.annotation.XmlAttribute;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AliasList implements Listener<AliasEvent>
{
private final static Logger mLog = LoggerFactory.getLogger(AliasList.class);
public static final String WILDCARD = "*";
public static final String REGEX_WILDCARD = ".";
private Map<String,Alias> mESN = new HashMap<>();
private Map<String,Alias> mFleetsync = new HashMap<>();
private Map<LoJackFunctionAndID,Alias> mLoJack = new HashMap<>();
private Map<String,Alias> mMDC1200 = new HashMap<>();
private Map<String,Alias> mMobileID = new HashMap<>();
private Map<String,Alias> mMPT1327 = new HashMap<>();
private Map<String,Alias> mSiteID = new HashMap<>();
private Map<Integer,Alias> mStatus = new HashMap<>();
private Map<String,Alias> mTalkgroup = new HashMap<>();
private Map<Integer,Alias> mUniqueID = new HashMap<>();
private List<WildcardID> mESNWildcards = new ArrayList<>();
private List<WildcardID> mMobileIDWildcards = new ArrayList<>();
private List<WildcardID> mFleetsyncWildcards = new ArrayList<>();
private List<WildcardID> mMDC1200Wildcards = new ArrayList<>();
private List<WildcardID> mMPT1327Wildcards = new ArrayList<>();
private List<WildcardID> mSiteWildcards = new ArrayList<>();
private List<WildcardID> mTalkgroupWildcards = new ArrayList<>();
private String mName;
/**
* List of aliases where all aliases share the same list name. Contains
* several methods for alias lookup from identifier values, like talkgroups.
*
* Responds to alias change events to keep the internal alias list updated.
*/
public AliasList(String name)
{
mName = name;
}
/**
* Adds the alias to this list
*/
public void addAlias(Alias alias)
{
if(alias != null)
{
for(AliasID aliasID : alias.getId())
{
addAliasID(aliasID, alias);
}
}
}
/**
* Adds the alias and alias identifier to the internal type mapping.
*/
private void addAliasID(AliasID id, Alias alias)
{
if(id.isValid())
{
try
{
switch(id.getType())
{
case ESN:
String esn = ((Esn) id).getEsn();
if(esn != null)
{
if(esn.contains(WILDCARD))
{
mESNWildcards.add(new WildcardID(esn));
Collections.sort(mESNWildcards);
}
mESN.put(esn, alias);
}
break;
case FLEETSYNC:
String fleetsync = ((FleetsyncID) id).getIdent();
if(fleetsync != null)
{
if(fleetsync.contains(WILDCARD))
{
mFleetsyncWildcards.add(new WildcardID(fleetsync));
Collections.sort(mFleetsyncWildcards);
}
mFleetsync.put(fleetsync, alias);
}
break;
case LOJACK:
mLoJack.put((LoJackFunctionAndID) id, alias);
break;
case MDC1200:
String mdc = ((MDC1200ID) id).getIdent();
if(mdc != null)
{
if(mdc.contains(WILDCARD))
{
mMDC1200Wildcards.add(new WildcardID(mdc));
Collections.sort(mMDC1200Wildcards);
}
mMDC1200.put(mdc, alias);
}
break;
case MPT1327:
String mpt = ((MPT1327ID) id).getIdent();
if(mpt != null)
{
if(mpt.contains(WILDCARD))
{
mMPT1327Wildcards.add(new WildcardID(mpt));
Collections.sort(mMPT1327Wildcards);
}
mMPT1327.put(mpt, alias);
}
break;
case MIN:
String min = ((Min) id).getMin();
if(min != null)
{
if(min.contains(WILDCARD))
{
mMobileIDWildcards.add(new WildcardID(min));
Collections.sort(mMobileIDWildcards);
}
mMobileID.put(min, alias);
}
break;
case LTR_NET_UID:
mUniqueID.put(((UniqueID) id).getUid(), alias);
break;
case SITE:
String siteID = ((SiteID) id).getSite();
if(siteID != null)
{
if(siteID.contains(WILDCARD))
{
mSiteWildcards.add(new WildcardID(siteID));
Collections.sort(mSiteWildcards);
}
mSiteID.put(siteID, alias);
}
break;
case STATUS:
mStatus.put(((StatusID) id).getStatus(), alias);
break;
case TALKGROUP:
String tgid = ((TalkgroupID) id).getTalkgroup();
if(tgid != null)
{
if(tgid.contains(WILDCARD))
{
mTalkgroupWildcards.add(new WildcardID(tgid));
Collections.sort(mTalkgroupWildcards);
}
mTalkgroup.put(tgid, alias);
}
break;
case BROADCAST_CHANNEL:
case NON_RECORDABLE:
case PRIORITY:
//We don't maintain lookups for these items
break;
default:
mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't ADD to lookup table");
break;
}
}
catch(Exception e)
{
mLog.error("Couldn't add alias ID " + id + " for alias " + alias);
}
}
}
/**
* Removes the alias from this list
*/
public void removeAlias(Alias alias)
{
if(alias != null)
{
for(AliasID aliasID : alias.getId())
{
removeAliasID(aliasID, alias);
}
}
}
private void removeWildcard(String value, List<WildcardID> wildcards)
{
if(value != null)
{
for(WildcardID wildcardID : wildcards)
{
if(wildcardID.value().equals(value))
{
wildcards.remove(wildcardID);
}
}
}
}
/**
* Removes the alias and alias identifier from internal mappings.
*/
private void removeAliasID(AliasID id, Alias alias)
{
if(id.isValid())
{
switch(id.getType())
{
case ESN:
String esn = ((Esn) id).getEsn();
if(esn != null)
{
if(esn.contains(WILDCARD))
{
removeWildcard(esn, mESNWildcards);
}
}
mESN.remove(esn);
break;
case FLEETSYNC:
String fleetsync = ((FleetsyncID) id).getIdent();
if(fleetsync != null)
{
if(fleetsync.contains(WILDCARD))
{
removeWildcard(fleetsync, mFleetsyncWildcards);
}
mFleetsync.remove(fleetsync);
}
break;
case LOJACK:
mLoJack.remove((LoJackFunctionAndID) id);
break;
case MDC1200:
String mdc = ((MDC1200ID) id).getIdent();
if(mdc != null)
{
if(mdc.contains(WILDCARD))
{
removeWildcard(mdc, mMDC1200Wildcards);
}
mMDC1200.remove(mdc);
}
break;
case MPT1327:
String mpt = ((MPT1327ID) id).getIdent();
if(mpt != null)
{
if(mpt.contains(WILDCARD))
{
removeWildcard(mpt, mMPT1327Wildcards);
}
mMPT1327.remove(mpt);
}
break;
case MIN:
String min = ((Min) id).getMin();
if(min != null)
{
if(min.contains(WILDCARD))
{
removeWildcard(min, mMobileIDWildcards);
}
mMobileID.remove(min);
}
break;
case LTR_NET_UID:
mUniqueID.remove(((UniqueID) id).getUid());
break;
case SITE:
mSiteID.remove(((SiteID) id).getSite());
break;
case STATUS:
mStatus.remove(((StatusID) id).getStatus());
break;
case TALKGROUP:
String tgid = ((TalkgroupID) id).getTalkgroup();
if(tgid != null)
{
if(tgid.contains(WILDCARD))
{
removeWildcard(tgid, mTalkgroupWildcards);
}
mTalkgroup.remove(tgid);
}
break;
case NON_RECORDABLE:
case PRIORITY:
case BROADCAST_CHANNEL:
//We don't maintain lookups for these items
break;
default:
mLog.warn("Unrecognized Alias ID Type:" + id.getType().name() + " - can't REMOVE from lookup table");
break;
}
}
}
/**
* Returns the first matching regex wildcard from the list of wildcards that matches the
* identifier.
*
* @param id to match
* @param wildcards to match against
* @return matching wildcard ID or null
*/
private String getWildcardMatch(String id, List<WildcardID> wildcards)
{
if(id != null)
{
for(WildcardID wildcard : wildcards)
{
if(wildcard.matches(id))
{
return wildcard.value();
}
}
}
return null;
}
/**
* Lookup alias by site ID
*/
public Alias getSiteID(String siteID)
{
Alias alias = null;
if(siteID != null)
{
alias = mSiteID.get(siteID);
if(alias == null)
{
String wildcard = getWildcardMatch(siteID, mSiteWildcards);
if(wildcard != null)
{
alias = mSiteID.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by status ID
*/
public Alias getStatus(int status)
{
return mStatus.get(status);
}
/**
* Lookup alias by Unique ID (UID)
*/
public Alias getUniqueID(int uniqueID)
{
return mUniqueID.get(uniqueID);
}
/**
* Lookup alias by ESN
*/
public Alias getESNAlias(String esn)
{
Alias alias = null;
if(esn != null)
{
alias = mESN.get(esn);
if(alias == null)
{
String wildcard = getWildcardMatch(esn, mESNWildcards);
if(wildcard != null)
{
alias = mESN.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by fleetsync ID
*/
public Alias getFleetsyncAlias(String ident)
{
Alias alias = null;
if(ident != null)
{
alias = mFleetsync.get(ident);
if(alias == null)
{
String wildcard = getWildcardMatch(ident, mFleetsyncWildcards);
if(wildcard != null)
{
alias = mFleetsync.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by lojack function and ID
*/
public Alias getLoJackAlias(Function function, String id)
{
if(id != null)
{
for(LoJackFunctionAndID lojack : mLoJack.keySet())
{
if(lojack.matches(function, id))
{
return mLoJack.get(lojack);
}
}
}
return null;
}
/**
* Lookup alias by MDC1200 ID
*/
public Alias getMDC1200Alias(String ident)
{
Alias alias = null;
if(ident != null)
{
alias = mMDC1200.get(ident);
if(alias == null)
{
String wildcard = getWildcardMatch(ident, mMDC1200Wildcards);
if(wildcard != null)
{
alias = mMDC1200.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by MPT1327 Ident
*/
public Alias getMPT1327Alias(String ident)
{
Alias alias = null;
if(ident != null)
{
alias = mMPT1327.get(ident);
if(alias == null)
{
String wildcard = getWildcardMatch(ident, mMPT1327Wildcards);
if(wildcard != null)
{
alias = mMPT1327.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by Mobile ID Number (MIN)
*/
public Alias getMobileIDNumberAlias(String ident)
{
Alias alias = null;
if(ident != null)
{
alias = mMobileID.get(ident);
if(alias == null)
{
String wildcard = getWildcardMatch(ident, mMobileIDWildcards);
if(wildcard != null)
{
alias = mMobileID.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by talkgroup
*
* @param tgid to use when searching for an alias
* @param includeWildcards true if you want to additionally search for a matching alias that contains wildcard(s)
* when there is not a direct match to the TGID.
*/
public Alias getTalkgroupAlias(String tgid, boolean includeWildcards)
{
Alias alias = null;
if(tgid != null)
{
alias = mTalkgroup.get(tgid);
if(alias == null && includeWildcards)
{
String wildcard = getWildcardMatch(tgid, mTalkgroupWildcards);
if(wildcard != null)
{
alias = mTalkgroup.get(wildcard);
}
}
}
return alias;
}
/**
* Lookup alias by talkgroup. Defaults to matching to wildcard talkgroups.
*/
public Alias getTalkgroupAlias(String tgid)
{
return getTalkgroupAlias(tgid, true);
}
/**
* Alias list name
*/
public String toString()
{
return mName;
}
/**
* Alias list name
*/
@XmlAttribute
public String getName()
{
return mName;
}
/**
* Indicates if this alias list has a non-null, non-empty name
*/
private boolean hasName()
{
return mName != null && !mName.isEmpty();
}
/**
* Receive alias change event notifications and modify this list accordingly
*/
@Override
public void receive(AliasEvent event)
{
if(hasName())
{
Alias alias = event.getAlias();
switch(event.getEvent())
{
case ADD:
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
{
addAlias(alias);
}
break;
case CHANGE:
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
{
addAlias(alias);
}
break;
case DELETE:
if(alias.getList() != null && getName().equalsIgnoreCase(alias.getList()))
{
removeAlias(alias);
}
break;
default:
break;
}
}
}
}