/**
* Copyright (C) IntelliBitz Technologies., Muthu Ramadoss
* 168, Medavakkam Main Road, Madipakkam, Chennai 600091, Tamilnadu, India.
* http://www.intellibitz.com
* training@intellibitz.com
* +91 44 2247 5106
* http://groups.google.com/group/etoe
* http://sted.sourceforge.net
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* STED, Copyright (C) 2007 IntelliBitz Technologies
* STED comes with ABSOLUTELY NO WARRANTY;
* This is free software, and you are welcome
* to redistribute it under the GNU GPL conditions;
*
* Visit http://www.gnu.org/ for GPL License terms.
*/
/**
* $Id:FontMapEntries.java 55 2007-05-19 05:55:34Z sushmu $
* $HeadURL: svn+ssh://sushmu@svn.code.sf.net/p/sted/code/FontTransliterator/trunk/src/intellibitz/sted/fontmap/FontMapEntries.java $
*/
package intellibitz.sted.fontmap;
import intellibitz.sted.event.FontMapEntriesChangeEvent;
import intellibitz.sted.event.IFontMapEntriesChangeListener;
import javax.swing.event.EventListenerList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Created by IntelliJ IDEA. User: Muthu Ramadoss Date: Oct 30, 2003 Time:
* 12:09:17 AM To change this template use Options | File Templates.
*/
public class FontMapEntries
implements ITransliterate.IEntries
{
// unique key
private Set<String> word1;
// unique value
private Set<String> word2;
// all words.. key + value.. unique
private Set<String> words;
// without rules
private Map<String, FontMapEntry> directEntries;
// map by id.. for faster access to entry
private Map<String, FontMapEntry> allEntries;
// directEntries with rules
private Map<String, FontMapEntry> ruleEntries;
private Stack<FontMapEntry> undo;
private Stack<FontMapEntry> redo;
private FontMapEntriesChangeEvent fontMapEntriesChangeEvent;
private EventListenerList fontMapEntriesChangeListeners;
public FontMapEntries()
{
directEntries = new TreeMap<String, FontMapEntry>();
allEntries = new HashMap<String, FontMapEntry>();
ruleEntries = new TreeMap<String, FontMapEntry>();
word1 = new TreeSet<String>();
word2 = new TreeSet<String>();
words = new TreeSet<String>();
undo = new Stack<FontMapEntry>();
redo = new Stack<FontMapEntry>();
fontMapEntriesChangeListeners = new EventListenerList();
}
/**
* Removes all mappings from this TreeMap.
*/
public void clear()
{
directEntries.clear();
allEntries.clear();
ruleEntries.clear();
word1.clear();
word2.clear();
words.clear();
clearUndoRedo();
}
public void clearUndoRedo()
{
undo.clear();
redo.clear();
}
/**
* Based on the edit, the collection needs to updated
*
* @param oldKey
* @param fontMapEntry
*/
public void reKey(FontMapEntry oldKey, FontMapEntry fontMapEntry)
{
// remove the old entry
remove(oldKey);
// add the new edited entry
addEntry(fontMapEntry);
}
/**
* @param entry
*/
public boolean add(FontMapEntry entry)
{
// if valid entry, and entry not already added
if (isValid(entry))
{
addEntry(entry);
return true;
}
return false;
}
private void addEntry(FontMapEntry entry)
{
final String key = entry.getFrom();
final String value = entry.getTo();
if (entry.isRulesSet())
{
// rule entries can have the same key with different set of rules
ruleEntries.put(entry.getId(), entry);
}
else
{
// key must be unique for entries without rules, so store by key
directEntries.put(key, entry);
}
allEntries.put(entry.getId(), entry);
word1.add(key);
word2.add(value);
// add all the words, key + value
words.add(key);
words.add(value);
fireFontMapEntriesChangeEvent();
}
public FontMapEntry remove(String id)
{
FontMapEntry fontMapEntry = remove(allEntries.get(id));
fireFontMapEntriesChangeEvent();
return fontMapEntry;
}
/**
* @param entry
* @return
*/
private FontMapEntry remove(FontMapEntry entry)
{
if (null == entry)
{
return null;
}
// try rule directEntries first
FontMapEntry removed = ruleEntries.remove(entry.getId());
// if not try blank directEntries
if (removed == null)
{
removed = directEntries.remove(entry.getFrom());
}
word1.remove(entry.getFrom());
word2.remove(entry.getTo());
// remove from words
words.remove(entry.getFrom());
words.remove(entry.getTo());
// remove from the master
allEntries.remove(entry.getId());
fireFontMapEntriesChangeEvent();
return removed;
}
public Collection remove(Collection<FontMapEntry> vals)
{
final Iterator<FontMapEntry> iterator = vals.iterator();
final ArrayList<FontMapEntry> removedEntries =
new ArrayList<FontMapEntry>(vals.size());
while (iterator.hasNext())
{
removedEntries.add(remove(iterator.next()));
}
fireFontMapEntriesChangeEvent();
return removedEntries;
}
/**
* if entry found in ruleEntries, returns true false otherwise
*
* @param word
* @return
*/
public List<FontMapEntry> isRuleFound(String word)
{
final Iterator<FontMapEntry> iterator = ruleEntries.values().iterator();
final List<FontMapEntry> list = new ArrayList<FontMapEntry>();
while (iterator.hasNext())
{
final FontMapEntry entry = iterator.next();
if (entry != null && word.equals(entry.getFrom()))
{
list.add(entry);
}
}
return list;
}
/**
* @param entry
* @return true if the entry is valid and can be added to this collection,
* false otherwise
*/
public boolean isValid(FontMapEntry entry)
{
return entry != null && entry.isValid() &&
(!entry.isRulesSet() ?
!directEntries.containsKey(entry.getFrom()) : true) &&
!allEntries
.containsValue(
entry);
}
/**
* @param entry
* @return true if the entry is valid and can be added to this collection,
* false otherwise
*/
public boolean isValidEdit(FontMapEntry entry)
{
return entry != null && entry.isValid() &&
!allEntries.containsValue(entry);
}
public ITransliterate.IEntry getDirectMapping(String word)
{
FontMapEntry entry = directEntries.get(word);
if (entry != null)
{
entry = findDirectMapping(entry, entry);
}
return entry;
}
private FontMapEntry findDirectMapping(FontMapEntry entry,
FontMapEntry root)
{
final FontMapEntry tmp = directEntries.get(entry.getTo());
if (tmp == null || tmp.getTo().equals(root.getFrom()))
{
return entry;
}
else
{
entry = findDirectMapping(tmp, root);
}
return entry;
}
public ITransliterate.IEntry getReverseMapping(String word)
{
// match the value for reverse transliterate
// if value matched, then return the key
for (FontMapEntry fontMapEntry : directEntries.values())
{
FontMapEntry entry = fontMapEntry;
if (entry.getTo().equals(word))
{
entry = findReverseMapping(entry, entry);
return entry;
}
}
return null;
}
private FontMapEntry findReverseMapping(FontMapEntry entry,
FontMapEntry root)
{
// match the value for reverse transliterate
// if value matched, then return the key
final Iterator<FontMapEntry> entries =
directEntries.values().iterator();
FontMapEntry tmp = null;
while (entries.hasNext())
{
final FontMapEntry val = entries.next();
if (val.getTo().equals(entry.getFrom()))
{
tmp = val;
break;
}
}
if (tmp == null || tmp.getFrom().equals(root.getTo()))
{
return entry;
}
else
{
entry = findReverseMapping(tmp, root);
}
return entry;
}
public boolean isInWord1(String word)
{
return word1.contains(word);
}
public boolean isInWord2(String word)
{
return word2.contains(word);
}
public Iterator<String> getAllWords()
{
return words.iterator();
}
public Iterator<String> getWord2()
{
return word2.iterator();
}
public Stack<FontMapEntry> getUndo()
{
return undo;
}
public Stack<FontMapEntry> getRedo()
{
return redo;
}
public Collection<FontMapEntry> values()
{
return allEntries.values();
}
public int size()
{
return allEntries.size();
}
public boolean isEmpty()
{
return allEntries.isEmpty();
}
public void addFontMapEntriesChangeListener(
IFontMapEntriesChangeListener changeListener)
{
fontMapEntriesChangeListeners
.add(IFontMapEntriesChangeListener.class, changeListener);
}
public void removeFontMapEntriesChangeListener(
IFontMapEntriesChangeListener changeListener)
{
fontMapEntriesChangeListeners
.remove(IFontMapEntriesChangeListener.class, changeListener);
}
// Notify all listeners that have registered interest for
// notification on this event type. The event instance
// is lazily created using the parameters passed into
// the fire method.
private void fireFontMapEntriesChangeEvent()
{
// Guaranteed to return a non-null array
final Object[] listeners =
fontMapEntriesChangeListeners.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2)
{
if (listeners[i] == IFontMapEntriesChangeListener.class)
{
// Lazily create the event:
if (fontMapEntriesChangeEvent == null)
{
fontMapEntriesChangeEvent =
new FontMapEntriesChangeEvent(this);
}
((IFontMapEntriesChangeListener) listeners[i + 1])
.stateChanged(fontMapEntriesChangeEvent);
}
}
}
}