From 11be5128bfdbec26b40c4b241e1882a8618cd59a Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Sat, 7 Jun 2003 09:33:54 +0000 Subject: [PATCH] implemented dictionary manager which ties into the HTML Checker --- build.xml | 1 + conf-sso/sp/dynamo.xml | 8 + conf/dynamo-venice.xml | 8 + conf/venice-db-init-mysql.sql | 5 + .../com/silverwrist/dynamo/Namespaces.java | 6 + .../dynamo/app/ApplicationContainer.java | 159 +- .../dynamo/dict/DatabaseDictOps.java | 64 + .../dynamo/dict/DatabaseDictOps_mysql.java | 225 + .../dynamo/dict/DatabaseDictionary.java | 250 + .../DatabaseDictionaryMessages.properties | 20 + .../dynamo/dict/DictionarySubsystem.java | 201 + .../dynamo/dict/ResourceDictionary.java | 288 + .../silverwrist/dynamo/dict/Spellchecker.java | 82 + .../com/silverwrist/dynamo/dict/Trie.java | 204 + .../com/silverwrist/dynamo/dict/en-us.dict | 45375 ++++++++++++++++ .../silverwrist/dynamo/dict/supplemental.dict | 135 + .../dynamo/except/DictionaryException.java | 58 + .../dynamo/iface/DynamoDictionary.java | 26 + .../iface/DynamoModifiableDictionary.java | 30 + .../dynamo/util/LoaderMessages.properties | 21 + .../silverwrist/dynamo/util/LoaderUtils.java | 154 + .../velocity/stylesheets/normal_base.vm | 5 + 22 files changed, 47176 insertions(+), 149 deletions(-) create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps_mysql.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionary.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionaryMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/DictionarySubsystem.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/ResourceDictionary.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/Spellchecker.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/Trie.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/en-us.dict create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/dict/supplemental.dict create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/except/DictionaryException.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoDictionary.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoModifiableDictionary.java create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/LoaderMessages.properties create mode 100644 src/dynamo-framework/com/silverwrist/dynamo/util/LoaderUtils.java diff --git a/build.xml b/build.xml index 5adc767..afb8994 100644 --- a/build.xml +++ b/build.xml @@ -145,6 +145,7 @@ + diff --git a/conf-sso/sp/dynamo.xml b/conf-sso/sp/dynamo.xml index 6b51a9f..80a898d 100644 --- a/conf-sso/sp/dynamo.xml +++ b/conf-sso/sp/dynamo.xml @@ -86,6 +86,14 @@ + + + + + + + + diff --git a/conf/dynamo-venice.xml b/conf/dynamo-venice.xml index c9c0a8a..68a9812 100644 --- a/conf/dynamo-venice.xml +++ b/conf/dynamo-venice.xml @@ -85,6 +85,14 @@ + + + + + + + + diff --git a/conf/venice-db-init-mysql.sql b/conf/venice-db-init-mysql.sql index 8a63a0d..8f03ae5 100644 --- a/conf/venice-db-init-mysql.sql +++ b/conf/venice-db-init-mysql.sql @@ -235,6 +235,11 @@ CREATE TABLE htmltagsets ( PRIMARY KEY (profid, tagset) ); +# Dictionary table. +CREATE TABLE dictionary ( + word VARCHAR(128) NOT NULL PRIMARY KEY # the word +); + #### following this line are Venice-specific tables #### # The table which defines menus. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java index 33ef448..67f3123 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java +++ b/src/dynamo-framework/com/silverwrist/dynamo/Namespaces.java @@ -80,4 +80,10 @@ public interface Namespaces public static final String HTMLCHECKER_PROPERTIES_NAMESPACE = "http://www.silverwrist.com/NS/dynamo/2003/06/05/htmlchecker.properties"; + /** + * Namespace for the spelling checker properties. + */ + public static final String SPELLCHECKER_PROPERTIES_NAMESPACE = + "http://www.silverwrist.com/NS/dynamo/2003/06/07/spellchecker.properties"; + } // end interface Namespaces diff --git a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java index 436ab23..5f9be58 100644 --- a/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java +++ b/src/dynamo-framework/com/silverwrist/dynamo/app/ApplicationContainer.java @@ -359,70 +359,6 @@ public class ApplicationContainer } // end getUltimateComponent - /** - * Finds an instance of the {@link com.silverwrist.dynamo.iface.ComponentInitialize ComponentInitialize} interface - * associated with the given object, either through implementation of the interface, or by querying its - * {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} implementation. - * - * @param obj The object to be queried. - * @return The instance of ComponentInitialize associated with the object, or null - * if there is no such instance. - */ - private static final ComponentInitialize getComponentInitialize(Object obj) - { - if (obj instanceof ComponentInitialize) - return (ComponentInitialize)obj; - if (obj instanceof ServiceProvider) - { // it may be a service provider interface - try - { // look for ComponentInitialize as a service - ServiceProvider sp = (ServiceProvider)obj; - ComponentInitialize rc = (ComponentInitialize)(sp.queryService(ComponentInitialize.class)); - return rc; - - } // end try - catch (NoSuchServiceException e) - { // do nothing here - } // end catch - - } // end if - - return null; // no dice! - - } // end getComponentInitialize - - /** - * Finds an instance of the {@link com.silverwrist.dynamo.iface.ComponentShutdown ComponentShutdown} interface - * associated with the given object, either through implementation of the interface, or by querying its - * {@link com.silverwrist.dynamo.iface.ServiceProvider ServiceProvider} implementation. - * - * @param obj The object to be queried. - * @return The instance of ComponentShutdown associated with the object, or null - * if there is no such instance. - */ - private static final ComponentShutdown getComponentShutdown(Object obj) - { - if (obj instanceof ComponentShutdown) - return (ComponentShutdown)obj; - if (obj instanceof ServiceProvider) - { // it may be a service provider interface - try - { // look for ComponentShutdown as a service - ServiceProvider sp = (ServiceProvider)obj; - ComponentShutdown rc = (ComponentShutdown)(sp.queryService(ComponentShutdown.class)); - return rc; - - } // end try - catch (NoSuchServiceException e) - { // do nothing here - } // end catch - - } // end if - - return null; // no dice! - - } // end getComponentShutdown - /** * Destroys all data associated with this ApplicationContainer. */ @@ -555,94 +491,19 @@ public class ApplicationContainer } // end processControlSection - private final NamedObject createNamedObject(Element config_root, ServiceProvider services, - Class extratest, String extratest_msg) - throws ConfigException + private final NamedObject createNamedObject(Element config_root, ServiceProvider services, Class extratest, + String extratest_msg) throws ConfigException { - XMLLoader loader = XMLLoader.get(); - String klassname = null; - try - { // get the classname and load it, and create an object - klassname = loader.getAttribute(config_root,"classname"); - if (logger.isDebugEnabled()) - { // output a proper debug message - Class desired = (extratest==null) ? NamedObject.class : extratest; - logger.debug("createNamedObject: Creating new NamedObject of class " + klassname - + ", which should implement " + desired.getName()); + NamedObject nobj = LoaderUtils.loadObject(config_root,services,extratest); + synchronized (this) + { // save its shutdown hook for later + ComponentShutdown sd = (ComponentShutdown)(LoaderUtils.query(ComponentShutdown.class,nobj)); + if (sd!=null) + m_shutdown_list.addFirst(sd); - } // end if + } // end synchronized block - Class klass = Class.forName(klassname); - if (!(NamedObject.class.isAssignableFrom(klass))) - { // this object is not a valid NamedObject - logger.error("object " + klassname + " does not implement NamedObject"); - ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", - "no.notDynamo"); - ce.setParameter(0,klassname); - throw ce; - - } // end if - - if ((extratest!=null) && !(extratest.isAssignableFrom(klass))) - { // this object is not a valid (whatever) - logger.error("object " + klassname + " does not implement " + extratest.getName()); - ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", - extratest_msg); - ce.setParameter(0,klassname); - throw ce; - - } // end if - - // instantiate the object, and initialize it as needed - Object rc = klass.newInstance(); - ComponentInitialize init = getComponentInitialize(rc); - if (init!=null) - init.initialize(config_root,services); - - synchronized (this) - { // save its shutdown hook for later - ComponentShutdown sd = getComponentShutdown(rc); - if (sd!=null) - m_shutdown_list.addFirst(sd); - - } // end synchronized block - - if (logger.isDebugEnabled()) - logger.debug("Object \"" + ((NamedObject)rc).getName() + "\" (of class " + klassname + ") created"); - - return (NamedObject)rc; - - } // end try - catch (XMLLoadException e) - { // error getting class name - throw the ConfigException - logger.error("XML loader failure",e); - throw new ConfigException(e); - - } // end catch - catch (ClassNotFoundException e) - { // the class was not found - ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", - "no.classNotFound"); - ce.setParameter(0,klassname); - throw ce; - - } // end catch - catch (IllegalAccessException e) - { // unable to create this object - ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", - "no.createError"); - ce.setParameter(0,klassname); - throw ce; - - } // end catch - catch (InstantiationException e) - { // unable to create this object - ConfigException ce = new ConfigException(ApplicationContainer.class,"ApplicationContainerMessages", - "no.createError"); - ce.setParameter(0,klassname); - throw ce; - - } // end catch + return nobj; } // end createNamedObject diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps.java b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps.java new file mode 100644 index 0000000..d43aee2 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps_mysql.java b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps_mysql.java new file mode 100644 index 0000000..911cd7d --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictOps_mysql.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionary.java b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionary.java new file mode 100644 index 0000000..dbd1125 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionary.java @@ -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 . + * + * 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 , + * 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 diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionaryMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionaryMessages.properties new file mode 100644 index 0000000..63167ff --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/DatabaseDictionaryMessages.properties @@ -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 . +# +# 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 , +# 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. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/DictionarySubsystem.java b/src/dynamo-framework/com/silverwrist/dynamo/dict/DictionarySubsystem.java new file mode 100644 index 0000000..01bfbaa --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/DictionarySubsystem.java @@ -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 . + * + * 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 , + * 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 = ""; + private static final String DEFAULT_END_ERROR = ""; + + /*-------------------------------------------------------------------------------- + * 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. + * + * 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 , + * 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 BackgroundTask 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 && (i1) + 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 diff --git a/src/dynamo-framework/com/silverwrist/dynamo/dict/Spellchecker.java b/src/dynamo-framework/com/silverwrist/dynamo/dict/Spellchecker.java new file mode 100644 index 0000000..0327889 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/dict/Spellchecker.java @@ -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 . + * + * 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 , + * 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. + * + * 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 , + * 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)) + { // 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='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. + * + * 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 , + * 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.except; + +public class DictionaryException extends ExternalException +{ + /*-------------------------------------------------------------------------------- + * Constructors + *-------------------------------------------------------------------------------- + */ + + /** + * Constructs a new DictionaryException instance. + * + * @param caller The classname of the class that's creating the exception. Its class loader + * and package name will be used, together with bundle, to find the + * resource bundle. + * @param bundle The name of the resource bundle to be loaded. + * @param message_id The identifier of the message to be loaded from the bundle. + */ + public DictionaryException(Class caller, String bundle, String message_id) + { + super(caller,bundle,message_id); + + } // end constructor + + /** + * Constructs a new DictionaryException instance. + * + * @param caller The classname of the class that's creating the exception. Its class loader + * and package name will be used, together with bundle, to find the + * resource bundle. + * @param bundle The name of the resource bundle to be loaded. + * @param message_id The identifier of the message to be loaded from the bundle. + * @param inner The exception to be nested inside this one. + */ + public DictionaryException(Class caller, String bundle, String message_id, Throwable inner) + { + super(caller,bundle,message_id,inner); + + } // end constructor + +} // end class DictionaryException diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoDictionary.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoDictionary.java new file mode 100644 index 0000000..9e234ea --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoDictionary.java @@ -0,0 +1,26 @@ +/* + * 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 . + * + * 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 , + * 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.iface; + +public interface DynamoDictionary +{ + public int size(); + + public boolean check(String word); + +} // end interface DynamoDictionary diff --git a/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoModifiableDictionary.java b/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoModifiableDictionary.java new file mode 100644 index 0000000..557dba2 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/iface/DynamoModifiableDictionary.java @@ -0,0 +1,30 @@ +/* + * 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 . + * + * 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 , + * 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.iface; + +import com.silverwrist.dynamo.except.DictionaryException; + +public interface DynamoModifiableDictionary extends DynamoDictionary +{ + public void add(String word) throws DictionaryException; + + public void remove(String word) throws DictionaryException; + + public void clear() throws DictionaryException; + +} // end interface DynamoModifiableDictionary diff --git a/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderMessages.properties b/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderMessages.properties new file mode 100644 index 0000000..67208eb --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderMessages.properties @@ -0,0 +1,21 @@ +# 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 . +# +# 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 , +# for Silverwrist Design Studios. Portions created by Eric J. Bowersox are +# Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. +# +# Contributor(s): +# --------------------------------------------------------------------------------- +# This file has been localized for the en_US locale +no.classNotFound=The object class {0} was not found. +no.createError=Unable to create new object of class {0}. +no.notDynamo=The object class {0} is not a valid Dynamo NamedObject, +no.notClass=The object class {0} is not a valid instance of {1}. diff --git a/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderUtils.java b/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderUtils.java new file mode 100644 index 0000000..7b580b8 --- /dev/null +++ b/src/dynamo-framework/com/silverwrist/dynamo/util/LoaderUtils.java @@ -0,0 +1,154 @@ +/* + * 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 . + * + * 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 , + * 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.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.*; + +public class LoaderUtils +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(LoaderUtils.class); + + /*-------------------------------------------------------------------------------- + * Constructor + *-------------------------------------------------------------------------------- + */ + + public LoaderUtils() + { // do nothing + } // end constructor + + /*-------------------------------------------------------------------------------- + * External static operations + *-------------------------------------------------------------------------------- + */ + + public static final Object query(Class iface, Object obj) + { + if (iface.isInstance(obj)) + return obj; + if (obj instanceof ServiceProvider) + { // try querying it for the service + try + { // query the service + return ((ServiceProvider)obj).queryService(iface); + + } // end try + catch (NoSuchServiceException e) + { // just fall out and return null + } // end catch + + } // end if + + return null; + + } // end query + + public static final NamedObject loadObject(Element config, ServiceProvider services, Class extratest) + throws ConfigException + { + XMLLoader loader = XMLLoader.get(); + String klassname = null; + try + { // get the class name for the object + klassname = loader.getAttribute(config,"classname"); + if (logger.isDebugEnabled()) + { // output a proper debug message + Class desired = (extratest==null) ? NamedObject.class : extratest; + logger.debug("loadObject: Creating new NamedObject of class " + klassname + ", which should implement " + + desired.getName()); + + } // end if + + // load the class + Class klass = Class.forName(klassname); + + // make sure the class represents a valid Dynamo NamedObject + if (!(NamedObject.class.isAssignableFrom(klass))) + { // this object is not a valid NamedObject + logger.error("object " + klassname + " does not implement NamedObject"); + ConfigException ce = new ConfigException(LoaderUtils.class,"LoaderMessages","no.notDynamo"); + ce.setParameter(0,klassname); + throw ce; + + } // end if + + // make sure it implements the class we want, too + if ((extratest!=null) && !(extratest.isAssignableFrom(klass))) + { // this object is not a valid (whatever) + logger.error("object " + klassname + " does not implement " + extratest.getName()); + ConfigException ce = new ConfigException(LoaderUtils.class,"LoaderMessages","no.notClass"); + ce.setParameter(0,klassname); + ce.setParameter(1,extratest.getName()); + throw ce; + + } // end if + + // instantiate the object + Object rc = klass.newInstance(); + + // initialize the object + ComponentInitialize init = (ComponentInitialize)query(ComponentInitialize.class,rc); + if (init!=null) + init.initialize(config,services); + + if (logger.isDebugEnabled()) + logger.debug("Object \"" + ((NamedObject)rc).getName() + "\" (of class " + klassname + ") created"); + + return (NamedObject)rc; + + } // end try + catch (XMLLoadException e) + { // error getting class name - throw the ConfigException + logger.error("XML loader failure",e); + throw new ConfigException(e); + + } // end catch + catch (ClassNotFoundException e) + { // the class was not found + ConfigException ce = new ConfigException(LoaderUtils.class,"LoaderMessages","no.classNotFound"); + ce.setParameter(0,klassname); + throw ce; + + } // end catch + catch (IllegalAccessException e) + { // unable to create this object + ConfigException ce = new ConfigException(LoaderUtils.class,"LoaderMessages","no.createError"); + ce.setParameter(0,klassname); + throw ce; + + } // end catch + catch (InstantiationException e) + { // unable to create this object + ConfigException ce = new ConfigException(LoaderUtils.class,"LoaderMessages","no.createError"); + ce.setParameter(0,klassname); + throw ce; + + } // end catch + + } // end loadObject + +} // end class LoaderUtils diff --git a/venice-data/velocity/stylesheets/normal_base.vm b/venice-data/velocity/stylesheets/normal_base.vm index 175a0f8..d1f8343 100644 --- a/venice-data/velocity/stylesheets/normal_base.vm +++ b/venice-data/velocity/stylesheets/normal_base.vm @@ -139,3 +139,8 @@ td.sidebox { font-weight: bold; font-color: red; } + +SPAN.spellingerror { + font-weight: bold; + font-color: red; + }