implemented dictionary manager which ties into the HTML Checker

This commit is contained in:
Eric J. Bowersox
2003-06-07 09:33:54 +00:00
parent 92a569cbbd
commit 11be5128bf
22 changed files with 47176 additions and 149 deletions
@@ -0,0 +1,64 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import com.silverwrist.dynamo.db.OpsBase;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
abstract class DatabaseDictOps extends OpsBase
{
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
protected DatabaseDictOps(DBConnectionPool pool)
{
super(pool);
} // end constructor
/*--------------------------------------------------------------------------------
* Abstract operations
*--------------------------------------------------------------------------------
*/
abstract int getSize() throws DatabaseException;
abstract boolean checkWord(String word) throws DatabaseException;
abstract boolean addWord(String word) throws DatabaseException;
abstract boolean removeWord(String word) throws DatabaseException;
abstract void clearDictionary() throws DatabaseException;
/*--------------------------------------------------------------------------------
* External static operations
*--------------------------------------------------------------------------------
*/
static DatabaseDictOps get(DBConnectionPool pool) throws ConfigException
{
return (DatabaseDictOps)get(pool,DatabaseDictOps.class.getClassLoader(),DatabaseDictOps.class.getName() + "_",
"DatabaseDictOps");
} // end get
} // end class DatabaseDictOps
@@ -0,0 +1,225 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import java.sql.*;
import com.silverwrist.util.*;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
public class DatabaseDictOps_mysql extends DatabaseDictOps
{
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public DatabaseDictOps_mysql(DBConnectionPool pool)
{
super(pool);
} // end constructor
/*--------------------------------------------------------------------------------
* Abstract implementations from class DatabaseDictOps
*--------------------------------------------------------------------------------
*/
int getSize() throws DatabaseException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// execute the count statement
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM dictionary;");
return SQLUtils.getReturnCountInt(rs,1);
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(conn);
} // end finally
} // end getSize
boolean checkWord(String word) throws DatabaseException
{
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// prepare and execute a statement
stmt = conn.prepareStatement("SELECT word FROM dictionary WHERE word = ?;");
stmt.setString(1,word);
rs = stmt.executeQuery();
return rs.next();
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(conn);
} // end finally
} // end checkWord
boolean addWord(String word) throws DatabaseException
{
Connection conn = null;
PreparedStatement stmt = null;
Statement stmt2 = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// lock the table
stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES dictionary WRITE;");
// see if the word's in the database
stmt = conn.prepareStatement("SELECT word FROM dictionary WHERE word = ?;");
stmt.setString(1,word);
rs = stmt.executeQuery();
if (rs.next())
return false;
SQLUtils.shutdown(rs);
rs = null;
SQLUtils.shutdown(stmt);
stmt = conn.prepareStatement("INSERT INTO dictionary (word) VALUES (?);");
stmt.setString(1,word);
stmt.executeUpdate();
return true;
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(stmt2);
SQLUtils.shutdown(conn);
} // end finally
} // end addWord
boolean removeWord(String word) throws DatabaseException
{
Connection conn = null;
PreparedStatement stmt = null;
Statement stmt2 = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// lock the table
stmt2 = conn.createStatement();
stmt2.executeUpdate("LOCK TABLES dictionary WRITE;");
// prepare and execute the delete statement
stmt = conn.prepareStatement("DELETE FROM dictionary WHERE word = ?;");
stmt.setString(1,word);
int rows = stmt.executeUpdate();
return (rows>0);
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(stmt2);
SQLUtils.shutdown(conn);
} // end finally
} // end removeWord
void clearDictionary() throws DatabaseException
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try
{ // get a connection
conn = getConnection();
// lock the table
stmt = conn.createStatement();
stmt.executeUpdate("LOCK TABLES dictionary WRITE;");
SQLUtils.shutdown(stmt);
// execute the statement
stmt = conn.createStatement();
stmt.executeUpdate("DELETE FROM dictionary;");
} // end try
catch (SQLException e)
{ // translate to a general DatabaseException
throw generalException(e);
} // end catch
finally
{ // shut everything down
MySQLUtils.unlockTables(conn);
SQLUtils.shutdown(rs);
SQLUtils.shutdown(stmt);
SQLUtils.shutdown(conn);
} // end finally
} // end clearDictionary
} // end class DatabaseDictOps_mysql
@@ -0,0 +1,250 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import java.util.*;
import org.apache.log4j.Logger;
import org.w3c.dom.*;
import com.silverwrist.util.xml.*;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.util.*;
public class DatabaseDictionary
implements NamedObject, ComponentInitialize, ComponentShutdown, DynamoModifiableDictionary
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(DatabaseDictionary.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String m_name; // name of this object
private DatabaseDictOps m_ops; // database operations object
private int m_cache_size = -1; // cached size
private WeakHashMap m_cache_yes; // words in dictionary
private WeakHashMap m_cache_no; // words not in dictionary
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public DatabaseDictionary()
{
m_cache_yes = new WeakHashMap();
m_cache_no = new WeakHashMap();
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface NamedObject
*--------------------------------------------------------------------------------
*/
public String getName()
{
return m_name;
} // end getName
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentInitialize
*--------------------------------------------------------------------------------
*/
/**
* Initialize the component.
*
* @param config_root Pointer to the section of the Dynamo XML configuration file that configures this
* particular component. This is to be considered "read-only" by the component.
* @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider}
* which provides initialization services to the component. This will include an implementation
* of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to
* get information about other objects previously initialized by the application.
* @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component
* configuration.
*/
public void initialize(Element config_root, ServiceProvider services) throws ConfigException
{
XMLLoader loader = XMLLoader.get();
String conn_name = null;
try
{ // verify the right node name
loader.verifyNodeName(config_root,"object");
// get the object's name
m_name = loader.getAttribute(config_root,"name");
// get the database configuration connection
DOMElementHelper config_root_h = new DOMElementHelper(config_root);
Element elt = loader.getSubElement(config_root_h,"database");
conn_name = loader.getAttribute(elt,"connection");
} // end try
catch (XMLLoadException e)
{ // error loading XML config data
throw new ConfigException(e);
} // end catch
// Get the database connection pool.
DBConnectionPool pool = GetObjectUtils.getDatabaseConnection(services,conn_name);
// Get the operations object.
m_ops = DatabaseDictOps.get(pool);
} // end initialize
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentShutdown
*--------------------------------------------------------------------------------
*/
public void shutdown()
{
m_ops.dispose();
m_ops = null;
} // end shutdown
/*--------------------------------------------------------------------------------
* Implementations from interface DynamoDictionary
*--------------------------------------------------------------------------------
*/
public synchronized int size()
{
if (m_cache_size<0)
{ // need to get the dictionary size
try
{ // get the size from the database
m_cache_size = m_ops.getSize();
} // end try
catch (DatabaseException e)
{ // whoops! error
logger.warn("DatabaseDictionary.size(): database error",e);
m_cache_size = -1;
} // end catch
} // end if
return m_cache_size;
} // end size
public synchronized boolean check(String word)
{
String real_word = word.toLowerCase();
if (m_cache_yes.containsKey(real_word))
return true;
else if (m_cache_no.containsKey(real_word))
return false;
boolean rc = false;
try
{ // check the database, stash result in cache
rc = m_ops.checkWord(real_word);
if (rc)
m_cache_yes.put(real_word,Boolean.TRUE);
else
m_cache_no.put(real_word,Boolean.FALSE);
} // end try
catch (DatabaseException e)
{ // database error
logger.warn("DatabaseDictionary.check(): database error",e);
rc = false;
} // end catch
return rc;
} // end check
/*--------------------------------------------------------------------------------
* Implementations from interface DynamoModifiableDictionary
*--------------------------------------------------------------------------------
*/
public synchronized void add(String word) throws DictionaryException
{
String real_word = word.toLowerCase();
try
{ // add to the dictionary
boolean added = m_ops.addWord(real_word);
if (added && (m_cache_size>=0))
m_cache_size++;
m_cache_yes.put(real_word,Boolean.TRUE);
m_cache_no.remove(real_word);
} // end try
catch (DatabaseException de)
{ // error adding to the database
throw new DictionaryException(DatabaseDictionary.class,"DatabaseDictionaryMessages","add.failed",de);
} // end catch
} // end add
public void remove(String word) throws DictionaryException
{
String real_word = word.toLowerCase();
try
{ // add to the dictionary
boolean removed = m_ops.removeWord(real_word);
if (removed && (m_cache_size>=0))
m_cache_size--;
m_cache_no.put(real_word,Boolean.FALSE);
m_cache_yes.remove(real_word);
} // end try
catch (DatabaseException de)
{ // error adding to the database
throw new DictionaryException(DatabaseDictionary.class,"DatabaseDictionaryMessages","remove.failed",de);
} // end catch
} // end remove
public void clear() throws DictionaryException
{
try
{ // zap it
m_ops.clearDictionary();
m_cache_size = 0;
m_cache_yes.clear();
} // end try
catch (DatabaseException de)
{ // error adding to the database
throw new DictionaryException(DatabaseDictionary.class,"DatabaseDictionaryMessages","clear.failed",de);
} // end catch
} // end clear
} // end class DatabaseDictionary
@@ -0,0 +1,20 @@
# The contents of this file are subject to the Mozilla Public License Version 1.1
# (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.mozilla.org/MPL/>.
#
# Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
# WARRANTY OF ANY KIND, either express or implied. See the License for the specific
# language governing rights and limitations under the License.
#
# The Original Code is the Venice Web Communities System.
#
# The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
# Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
#
# Contributor(s):
# ---------------------------------------------------------------------------------
# This file has been localized for the en_US locale
add.failed=Unable to add word to database.
remove.failed=Unable to remove word from database.
clear.failed=Unable to clear database dictionary.
@@ -0,0 +1,201 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import java.util.*;
import org.apache.log4j.Logger;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.util.xml.*;
import com.silverwrist.dynamo.Namespaces;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.util.*;
public class DictionarySubsystem
implements NamedObject, ComponentInitialize, ComponentShutdown, HTMLCheckerConfigurator
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(DictionarySubsystem.class);
private static final String DEFAULT_BEGIN_ERROR = "<span class=\"spellingerror\">";
private static final String DEFAULT_END_ERROR = "</span>";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String m_name; // name of this object
private LinkedList m_shutdown_list; // object shutdown list
private Hashtable m_dictionaries; // current dictionaries
private Hashtable m_modifiable_dictionaries; // current modifiable dictionaries
private ComponentShutdown m_htmlchecker; // HTML checker configurator
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public DictionarySubsystem()
{
m_shutdown_list = new LinkedList();
m_dictionaries = new Hashtable();
m_modifiable_dictionaries = new Hashtable();
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface NamedObject
*--------------------------------------------------------------------------------
*/
public String getName()
{
return m_name;
} // end getName
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentInitialize
*--------------------------------------------------------------------------------
*/
/**
* Initialize the component.
*
* @param config_root Pointer to the section of the Dynamo XML configuration file that configures this
* particular component. This is to be considered "read-only" by the component.
* @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider}
* which provides initialization services to the component. This will include an implementation
* of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to
* get information about other objects previously initialized by the application.
* @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component
* configuration.
*/
public void initialize(Element config_root, ServiceProvider services) throws ConfigException
{
logger.info("DictionarySubsystem initializing");
XMLLoader loader = XMLLoader.get();
List subobjects = null;
try
{ // verify the right node name
loader.verifyNodeName(config_root,"object");
// get the object's name
m_name = loader.getAttribute(config_root,"name");
// get the subobject nodes to load
subobjects = loader.getMatchingSubElements(config_root,"dictionary");
} // end try
catch (XMLLoadException e)
{ // error loading XML config data
throw new ConfigException(e);
} // end catch
// load and initialize the dictionary subobjects
Iterator it = subobjects.iterator();
while (it.hasNext())
{ // initialize all the dictionary subobjects
Element droot = (Element)(it.next());
DynamoDictionary dict = (DynamoDictionary)(LoaderUtils.loadObject(droot,services,DynamoDictionary.class));
ComponentShutdown cs = (ComponentShutdown)(LoaderUtils.query(ComponentShutdown.class,dict));
if (cs!=null)
m_shutdown_list.addFirst(cs);
String dictname = ((NamedObject)dict).getName();
m_dictionaries.put(dictname,dict);
if (dict instanceof DynamoModifiableDictionary)
m_modifiable_dictionaries.put(dictname,dict);
} // end while
// Link us into the HTML Checker's configurators list.
HTMLCheckerConfigRegister creg =
(HTMLCheckerConfigRegister)(services.queryService(HTMLCheckerConfigRegister.class));
m_htmlchecker = creg.registerConfigurator(this);
} // end initialize
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentShutdown
*--------------------------------------------------------------------------------
*/
public void shutdown()
{
m_htmlchecker.shutdown();
m_htmlchecker = null;
m_dictionaries.clear();
m_modifiable_dictionaries.clear();
while (m_shutdown_list.size()>0)
{ // shut down all the components
ComponentShutdown cs = (ComponentShutdown)(m_shutdown_list.removeFirst());
cs.shutdown();
} // end while
} // end shutdown
/*--------------------------------------------------------------------------------
* Implementations from interface HTMLCheckerConfigurator
*--------------------------------------------------------------------------------
*/
public void configure(HTMLCheckerProfile profile)
{
boolean enable =
((Boolean)(PropertyUtils.getPropertyDefault(profile,Namespaces.SPELLCHECKER_PROPERTIES_NAMESPACE,
"enable",Boolean.FALSE))).booleanValue();
if (enable)
{ // get the list of dictionaries
String dictnames = PropertyUtils.getPropertyDefault(profile,Namespaces.SPELLCHECKER_PROPERTIES_NAMESPACE,
"dictionaries","").toString();
String[] dictname_list = StringUtils.split1(dictnames,',');
ArrayList dict_list = new ArrayList();
for (int i=0; i<dictname_list.length; i++)
{ // locate the dictionaries and plug them in
DynamoDictionary d = (DynamoDictionary)(m_dictionaries.get(dictname_list[i].trim()));
if (d!=null)
dict_list.add(d);
} // end for
DynamoDictionary[] dicts = new DynamoDictionary[dict_list.size()];
dict_list.toArray(dicts);
// get the begin error and end error sequences
String begin_error = PropertyUtils.getPropertyDefault(profile,Namespaces.SPELLCHECKER_PROPERTIES_NAMESPACE,
"begin.error",DEFAULT_BEGIN_ERROR).toString();
String end_error = PropertyUtils.getPropertyDefault(profile,Namespaces.SPELLCHECKER_PROPERTIES_NAMESPACE,
"end.error",DEFAULT_END_ERROR).toString();
// load a spellchucker, ready to go!
profile.addWordRewriter(new Spellchecker(dicts,begin_error,end_error));
} // end if
} // end configure
} // end class DictionarySubsystem
@@ -0,0 +1,288 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import java.io.*;
import org.apache.log4j.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.util.xml.*;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
public class ResourceDictionary implements NamedObject, ComponentInitialize, ComponentShutdown, DynamoDictionary
{
/*--------------------------------------------------------------------------------
* Internal class that loads the trie
*--------------------------------------------------------------------------------
*/
private static class TrieLoader implements BackgroundTask
{
/*====================================================================
* Attributes
*====================================================================
*/
private Reader m_rdr;
private String m_rdrname;
private volatile Trie m_trie = null;
/*====================================================================
* Constructor
*====================================================================
*/
TrieLoader(Reader rdr, String rdrname)
{
m_rdr = rdr;
m_rdrname = rdrname;
} // end constructor
/*====================================================================
* Implementations from interface BackgroundTask
*====================================================================
*/
/**
* Execute the background task.
*
* @param services A {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} which provides all
* services that the <CODE>BackgroundTask</CODE> is permitted to use.
*/
public void run(ServiceProvider services)
{
if (logger.isDebugEnabled())
logger.debug("now loading resource " + m_rdrname);
Trie trie = new Trie();
try
{ // create the appropriate reader
BufferedReader r = new BufferedReader(m_rdr);
int counter = 0;
String word = r.readLine();
while (word!=null)
{ // load words into the lexicon
trie.add(word);
word = r.readLine();
if (((++counter % 1000)==0) && logger.isDebugEnabled())
logger.debug("loaded " + counter + " words");
} // end while
r.close();
if (logger.isDebugEnabled())
logger.debug("finished loading resource " + m_rdrname + ", " + counter + " words loaded");
} // end try
catch (IOException e)
{ // trap it and go on to the next one
logger.error("IOException loading resource " + m_rdrname,e);
} // end catch
synchronized (this)
{ // save off the trie
m_trie = trie;
m_rdr = null;
notifyAll();
} // end synchronized block
System.gc(); // clean up any crap left over from the load
} // end run
/*====================================================================
* External operations
*====================================================================
*/
synchronized Trie getTrie()
{
while (m_trie==null)
{ // not loaded yet - wait for it
if (logger.isDebugEnabled())
logger.debug("waiting for trie to load...");
try
{ // park the thread here until we know what's up
wait();
} // end try
catch (InterruptedException e)
{ // do nothing
} // end catch
} // end while
return m_trie;
} // end getTrie
} // end class TrieLoader
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Logger logger = Logger.getLogger(ResourceDictionary.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String m_name; // name of this object
private TrieLoader m_loader; // contains the trie we're loading
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ResourceDictionary()
{ // do nothing
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private static final boolean checkHyphenates(Trie trie, String word)
{
if (word.indexOf('-')<0)
return false; // no hyphenates
String[] parts = StringUtils.split1(word,'-');
boolean ok = true;
for (int i=0; ok && (i<parts.length); i++)
if (parts[i].length()>1)
ok = trie.check(parts[i]);
return ok;
} // end checkHyphenates
/*--------------------------------------------------------------------------------
* Implementations from interface NamedObject
*--------------------------------------------------------------------------------
*/
public String getName()
{
return m_name;
} // end getName
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentInitialize
*--------------------------------------------------------------------------------
*/
/**
* Initialize the component.
*
* @param config_root Pointer to the section of the Dynamo XML configuration file that configures this
* particular component. This is to be considered "read-only" by the component.
* @param services An implementation of {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider}
* which provides initialization services to the component. This will include an implementation
* of {@link com.silverwrist.dynamo.iface.ObjectProvider ObjectProvider} which may be used to
* get information about other objects previously initialized by the application.
* @exception com.silverwrist.dynamo.except.ConfigException If an error is encountered in the component
* configuration.
*/
public void initialize(Element config_root, ServiceProvider services) throws ConfigException
{
XMLLoader loader = XMLLoader.get();
String resource_name = null;
try
{ // verify the right node name
loader.verifyNodeName(config_root,"object");
// get the object's name
m_name = loader.getAttribute(config_root,"name");
// get the name of the resource to load
resource_name = loader.getAttribute(config_root,"resource");
} // end try
catch (XMLLoadException e)
{ // error loading XML config data
throw new ConfigException(e);
} // end catch
// Create the loader object.
m_loader = new TrieLoader(new InputStreamReader(getClass().getResourceAsStream(resource_name)),resource_name);
// Queue the loader up as a background task.
BackgroundScheduler sched = (BackgroundScheduler)(services.queryService(BackgroundScheduler.class));
sched.runTaskLater(m_loader,false);
} // end initialize
/*--------------------------------------------------------------------------------
* Implementations from interface ComponentShutdown
*--------------------------------------------------------------------------------
*/
public void shutdown()
{
m_loader = null;
} // end shutdown
/*--------------------------------------------------------------------------------
* Implementations from interface DynamoDictionary
*--------------------------------------------------------------------------------
*/
public int size()
{
return m_loader.getTrie().size();
} // end size
public boolean check(String word)
{
if (word==null)
return false;
if (word.length()<=1)
return true;
String real_word = word.toLowerCase();
Trie trie = m_loader.getTrie();
if (trie.check(real_word))
return true;
if (real_word.endsWith("'s"))
{ // check the non-possessive form
String base = real_word.substring(0,real_word.length()-2);
if (trie.check(base))
return true;
else
return checkHyphenates(trie,base);
} // end if
else // check all hyphenates
return checkHyphenates(trie,real_word);
} // end check
} // end class ResourceDictionary
@@ -0,0 +1,82 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
import com.silverwrist.dynamo.Namespaces;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.htmlcheck.MarkupData;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.util.*;
class Spellchecker implements HTMLRewriter
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static QualifiedNameKey NAME = new QualifiedNameKey(Namespaces.SPELLCHECKER_PROPERTIES_NAMESPACE,"errors");
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private DynamoDictionary[] m_dicts;
private String m_begin_error;
private String m_end_error;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
Spellchecker(DynamoDictionary[] dicts, String begin_error, String end_error)
{
m_dicts = dicts;
m_begin_error = begin_error;
m_end_error = end_error;
} // end constructor
/*--------------------------------------------------------------------------------
* Implementations from interface HTMLRewriter
*--------------------------------------------------------------------------------
*/
public QualifiedNameKey getName()
{
return NAME;
} // end getName
public MarkupData rewrite(String data, String prefix, String suffix, HTMLRewriterSite site)
{
for (int i=0; i<m_dicts.length; i++)
{ // check word against all the dictionaries we have
if (m_dicts[i].check(data))
return null;
} // end for
// not found - return word with error highlighted
return new MarkupData(prefix,m_begin_error,data,m_end_error,suffix);
} // end rewrite
} // end class Spellchecker
@@ -0,0 +1,204 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (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.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dict;
class Trie
{
/*--------------------------------------------------------------------------------
* Internal node class
*--------------------------------------------------------------------------------
*/
private static final class Node
{
/*====================================================================
* Attributes
*====================================================================
*/
private boolean m_term = false;
private Node[] m_ptr = null;
/*====================================================================
* Constructor
*====================================================================
*/
Node()
{ // do nothing
} // end constructor
/*====================================================================
* External operations
*====================================================================
*/
final Node getRef(char ltr)
{
if (m_ptr==null)
return null;
int x = permute(ltr);
return (x<m_ptr.length) ? m_ptr[x] : null;
} // end getRef
final void setRef(char ltr, Node node)
{
int x = permute(ltr);
if ((m_ptr==null) || (x>=m_ptr.length))
{ // the internal array needs to be expanded
Node[] new_array = new Node[x+1];
int i = 0;
if (m_ptr!=null)
{ // copy the old portion of the array over
System.arraycopy(m_ptr,0,new_array,0,m_ptr.length);
i = m_ptr.length;
} // end if
while (i<new_array.length)
new_array[i++] = null; // null out the new portion of the array
m_ptr = new_array; // save off the new reference
} // end if
m_ptr[x] = node; // save reference
} // end setRef
final boolean isTerminal()
{
return m_term;
} // end isTerminal
final void setTerminal()
{
m_term = true;
} // end setTerminal
} // end class Node
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final int[] PERMUTE_TAB =
{ 8, 22, 13, 10, 2, 14, 19, 11, 6, 26, 24, 12, 17, 4, 7, 15, 25, 5, 9, 3, 16, 21, 20, 23, 18, 27 };
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private Node m_root;
private int m_count;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
Trie()
{
m_root = new Node();
m_count = 0;
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
private static final boolean validchar(char ch)
{
return ((ch>='a') && (ch<='z')) || (ch=='\'') || (ch=='-');
}
private static final int permute(char ltr)
{
if (ltr=='-')
return 0;
else if (ltr=='\'')
return 1;
else
return PERMUTE_TAB[ltr - 'a'];
} // end permute
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
int size()
{
return m_count;
} // end size
boolean check(String s)
{
char[] arr = s.toLowerCase().toCharArray();
Node cur = m_root;
for (int i=0; i<arr.length; i++)
{ // navigate down the trie
if (!validchar(arr[i]))
return false;
cur = cur.getRef(arr[i]);
if (cur==null)
return false;
} // end for
return cur.isTerminal();
} // end check
void add(String s)
{
char[] arr = s.toLowerCase().toCharArray();
Node cur = m_root;
for (int i=0; i<arr.length; i++)
{ // navigate down the trie
if (!validchar(arr[i]))
return;
// navigate down one level
Node next = cur.getRef(arr[i]);
if (next==null)
{ // create a new node and set its reference
next = new Node();
cur.setRef(arr[i],next);
} // end if
cur = next;
} // end for
cur.setTerminal();
m_count++;
} // end add
} // end class Trie
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,135 @@
acmecity
advogato
ain't
anime
anla'shok
bajor
bios
boitano
boromax
bungee
can't
cartman
cdt
checkouts
communityware
couldn't
crewmember
crewmembers
cst
deflector
deflectors
delenn
didn't
dilithium
docking
doesn't
don't
downtime
edt
email
eminds
entil'zha
eps
erbo
est
faux
fett
followup
franklin
fucking
gamey
hairstyle
hairstyles
hasn't
haven't
he'd
html
i'd
i'll
i'm
i've
inducers
it'd
khan
kubla
kyle
lafou
ma'am
maddog
marillion
mdt
minbar
minbari
mom
mp
mr
mst
mustn't
nacelle
nacelles
navigational
ops
padd
paperclip
pdt
peachy
pic
planitia
planum
predation
predators
privs
psi
pst
refit
refitting
replicator
repost
reposted
rom
runabout
salchow
salchows
sarcastically
shouldn't
silverwrist
snarf
snarfage
snarfer
snarfing
snazzy
sourceforge
spaceport
spellchecker
spellchucker
spelunker
spelunkers
st
starbase
starfleet
starship
straightening
stunted
terrence
they're
turbolift
tuzanor
umbilical
umbilicals
unread
url
utne
valen
veni
we'll
we're
we've
webb
webbme
won't
wouldn't
wow
you'd
you'll
you're