com.planetj.taste.impl.model.jdbc
Class AbstractJDBCDataModel

java.lang.Object
  extended by com.planetj.taste.impl.model.jdbc.AbstractJDBCDataModel
All Implemented Interfaces:
Refreshable, DataModel, JDBCDataModel
Direct Known Subclasses:
GenericJDBCDataModel, MySQLJDBCDataModel

public abstract class AbstractJDBCDataModel
extends java.lang.Object
implements JDBCDataModel

An abstract superclass for JDBC-related DataModel implementations, providing most of the common functionality that any such implementation would need.

Performance will be a concern with any JDBC-based DataModel. There are going to be lots of simultaneous reads and some writes to one table. Make sure the table is set up optimally -- for example, you'll want to establish indexes.

You'll also want to use connection pooling of some kind. Most J2EE containers like Tomcat provide connection pooling, so make sure the DataSource it exposes is using pooling. Outside a J2EE container, you can use packages like Jakarta's DBCP to create a DataSource on top of your database whose Connections are pooled.

Also note: this default implementation assumes that the user and item ID keys are Strings, for maximum flexibility. You can override this behavior by subclassing an implementation and overriding buildItem(String) and buildUser(String, List). If you don't, just make sure you use Strings as IDs throughout your code. If your IDs are really numeric, and you use, say, Long for IDs in the rest of your code, you will run into subtle problems because the Long values won't be equal to or compare correctly to the underlying String key values.

Author:
Sean Owen

Field Summary
static java.lang.String DEFAULT_DATASOURCE_NAME
           
static java.lang.String DEFAULT_ITEM_ID_COLUMN
           
static java.lang.String DEFAULT_PREFERENCE_COLUMN
           
static java.lang.String DEFAULT_PREFERENCE_TABLE
           
static java.lang.String DEFAULT_USER_ID_COLUMN
           
 
Constructor Summary
protected AbstractJDBCDataModel(javax.sql.DataSource dataSource, java.lang.String getUserSQL, java.lang.String getNumItemsSQL, java.lang.String getNumUsersSQL, java.lang.String setPreferenceSQL, java.lang.String removePreferenceSQL, java.lang.String getUsersSQL, java.lang.String getItemsSQL, java.lang.String getItemSQL, java.lang.String getPrefsForItemSQL, java.lang.String getUsersPreferringItemSQL)
           
 
Method Summary
protected  Item buildItem(java.lang.String id)
          Default implementation which returns a new GenericItem with String IDs.
protected  Preference buildPreference(User user, Item item, double value)
          Subclasses may override to return a different Preference implementation.
protected  User buildUser(java.lang.String id, java.util.List<Preference> prefs)
          Default implementation which returns a new GenericUser with String IDs.
 javax.sql.DataSource getDataSource()
           
 Item getItem(java.lang.Object id)
          
 Item getItem(java.lang.Object id, boolean assumeExists)
          
 java.lang.Iterable<? extends Item> getItems()
          
 int getNumItems()
          
 int getNumUsers()
          
 java.lang.Iterable<? extends Preference> getPreferencesForItem(java.lang.Object itemID)
          
 Preference[] getPreferencesForItemAsArray(java.lang.Object itemID)
           
 User getUser(java.lang.Object id)
          
 java.lang.Iterable<? extends User> getUsers()
          
static javax.sql.DataSource lookupDataSource(java.lang.String dataSourceName)
          Looks up a DataSource by name from JNDI.
 void refresh()
          

Triggers "refresh" -- whatever that means -- of the implementation.

 void removePreference(java.lang.Object userID, java.lang.Object itemID)
          

Removes a particular preference for a user.

 void setPreference(java.lang.Object userID, java.lang.Object itemID, double value)
          

Sets a particular preference (item plus rating) for a user.

 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_DATASOURCE_NAME

public static final java.lang.String DEFAULT_DATASOURCE_NAME
See Also:
Constant Field Values

DEFAULT_PREFERENCE_TABLE

public static final java.lang.String DEFAULT_PREFERENCE_TABLE
See Also:
Constant Field Values

DEFAULT_USER_ID_COLUMN

public static final java.lang.String DEFAULT_USER_ID_COLUMN
See Also:
Constant Field Values

DEFAULT_ITEM_ID_COLUMN

public static final java.lang.String DEFAULT_ITEM_ID_COLUMN
See Also:
Constant Field Values

DEFAULT_PREFERENCE_COLUMN

public static final java.lang.String DEFAULT_PREFERENCE_COLUMN
See Also:
Constant Field Values
Constructor Detail

AbstractJDBCDataModel

protected AbstractJDBCDataModel(javax.sql.DataSource dataSource,
                                java.lang.String getUserSQL,
                                java.lang.String getNumItemsSQL,
                                java.lang.String getNumUsersSQL,
                                java.lang.String setPreferenceSQL,
                                java.lang.String removePreferenceSQL,
                                java.lang.String getUsersSQL,
                                java.lang.String getItemsSQL,
                                java.lang.String getItemSQL,
                                java.lang.String getPrefsForItemSQL,
                                java.lang.String getUsersPreferringItemSQL)
Method Detail

lookupDataSource

@NotNull
public static javax.sql.DataSource lookupDataSource(java.lang.String dataSourceName)
                                             throws TasteException

Looks up a DataSource by name from JNDI. "java:comp/env/" is prepended to the argument before looking up the name in JNDI.

Parameters:
dataSourceName - JNDI name where a DataSource is bound (e.g. "jdbc/taste")
Returns:
DataSource under that JNDI name
Throws:
TasteException - if a JNDI error occurs

getDataSource

@NotNull
public javax.sql.DataSource getDataSource()
Specified by:
getDataSource in interface JDBCDataModel
Returns:
the DataSource that this instance is using
Since:
1.4.6

getUsers

@NotNull
public final java.lang.Iterable<? extends User> getUsers()
                                                  throws TasteException

Specified by:
getUsers in interface DataModel
Returns:
a List of all Users in the model, ordered by User
Throws:
TasteException - if an error occurs while accessing the data

getUser

@NotNull
public final User getUser(java.lang.Object id)
                   throws TasteException

Specified by:
getUser in interface DataModel
Parameters:
id - user ID
Returns:
User who has that ID
Throws:
java.util.NoSuchElementException - if there is no such user
TasteException - if an error occurs while accessing the data

getItems

@NotNull
public final java.lang.Iterable<? extends Item> getItems()
                                                  throws TasteException

Specified by:
getItems in interface DataModel
Returns:
a List of all Items in the model, order by Item
Throws:
TasteException - if an error occurs while accessing the data

getItem

@NotNull
public final Item getItem(java.lang.Object id)
                   throws TasteException

Specified by:
getItem in interface DataModel
Parameters:
id - item ID
Returns:
Item that has that ID
Throws:
TasteException - if an error occurs while accessing the data

getItem

@NotNull
public final Item getItem(java.lang.Object id,
                                  boolean assumeExists)
                   throws TasteException

Specified by:
getItem in interface JDBCDataModel
assumeExists - assume the item exists; don't consult the underlying database. This is a necessary performance enhancement shortcut needed by slope one recommenders
Throws:
TasteException
See Also:
DataModel.getItem(Object)

getPreferencesForItem

@NotNull
public final java.lang.Iterable<? extends Preference> getPreferencesForItem(java.lang.Object itemID)
                                                                     throws TasteException

Specified by:
getPreferencesForItem in interface DataModel
Parameters:
itemID - item ID
Returns:
all existing Preferences expressed for that item, ordered by User
Throws:
TasteException - if an error occurs while accessing the data

getPreferencesForItemAsArray

@NotNull
public final Preference[] getPreferencesForItemAsArray(java.lang.Object itemID)
                                                throws TasteException
Specified by:
getPreferencesForItemAsArray in interface DataModel
Parameters:
itemID - item ID
Returns:
all existing Preferences expressed for that item, ordered by User, as an array
Throws:
TasteException - if an error occurs while accessing the data

getNumItems

public final int getNumItems()
                      throws TasteException

Specified by:
getNumItems in interface DataModel
Returns:
total number of Items known to the model. This is generally the union of all Items preferred by at least one User but could include more.
Throws:
TasteException - if an error occurs while accessing the data

getNumUsers

public final int getNumUsers()
                      throws TasteException

Specified by:
getNumUsers in interface DataModel
Returns:
total number of Users known to the model.
Throws:
TasteException - if an error occurs while accessing the data

setPreference

public final void setPreference(java.lang.Object userID,
                                java.lang.Object itemID,
                                double value)
                         throws TasteException

Sets a particular preference (item plus rating) for a user.

Specified by:
setPreference in interface DataModel
Parameters:
userID - user to set preference for
itemID - item to set preference for
value - preference value
Throws:
TasteException - if an error occurs while accessing the data

removePreference

public final void removePreference(java.lang.Object userID,
                                   java.lang.Object itemID)
                            throws TasteException

Removes a particular preference for a user.

Specified by:
removePreference in interface DataModel
Parameters:
userID - user from which to remove preference
itemID - item to remove preference for
Throws:
TasteException - if an error occurs while accessing the data

refresh

public final void refresh()

Triggers "refresh" -- whatever that means -- of the implementation. The general contract is that any Refreshable should always leave itself in a consistent, operational state, and that the refresh atomically updates internal state from old to new.

Specified by:
refresh in interface Refreshable

buildUser

@NotNull
protected User buildUser(java.lang.String id,
                                 java.util.List<Preference> prefs)

Default implementation which returns a new GenericUser with String IDs. Subclasses may override to return a different User implementation.

Parameters:
id - user ID
prefs - user preferences
Returns:
GenericUser by default

buildItem

@NotNull
protected Item buildItem(java.lang.String id)

Default implementation which returns a new GenericItem with String IDs. Subclasses may override to return a different Item implementation.

Parameters:
id - item ID
Returns:
GenericItem by default

buildPreference

@NotNull
protected Preference buildPreference(User user,
                                             Item item,
                                             double value)
Subclasses may override to return a different Preference implementation.

Parameters:
user - User
item - Item
Returns:
GenericPreference by default