Widened. Added support for overriding the site on a particular request.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@2081 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2007-04-03 22:08:27 +00:00
parent b045017252
commit 3bb6abd2ad
3 changed files with 83 additions and 91 deletions
@@ -26,23 +26,28 @@ import java.util.Iterator;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
* Used by default and for systems that have no need to discriminate * Used by default and for systems that have no need to discriminate between different sites in
* between different sites in their web applications. * their web applications.
*/ */
public class IndiscriminateSiteIdentifier implements SiteIdentifier public class IndiscriminateSiteIdentifier implements SiteIdentifier
{ {
/** /**
* Always returns {@link #DEFAULT_SITE_ID} regardless of the * Always returns {@link #DEFAULT_SITE_ID} regardless of the information in the request.
* information in the request.
*/ */
public int identifySite (HttpServletRequest req) public int identifySite (HttpServletRequest req)
{ {
return DEFAULT_SITE_ID; // check whether our site id was overridden
Integer override = (Integer)req.getAttribute(SITE_ID_OVERRIDE_KEY);
if (override != null) {
return override;
} else {
return DEFAULT_SITE_ID;
}
} }
/** /**
* Always returns {@link #DEFAULT_SITE_STRING} regardless of the value * Always returns {@link #DEFAULT_SITE_STRING} regardless of the value of the supplied
* of the supplied identifer. * identifer.
*/ */
public String getSiteString (int siteId) public String getSiteString (int siteId)
{ {
@@ -50,8 +55,7 @@ public class IndiscriminateSiteIdentifier implements SiteIdentifier
} }
/** /**
* Always returns {@link #DEFAULT_SITE_ID} regardless of the value of * Always returns {@link #DEFAULT_SITE_ID} regardless of the value of the supplied string.
* the supplied string.
*/ */
public int getSiteId (String siteString) public int getSiteId (String siteString)
{ {
@@ -46,35 +46,31 @@ import com.samskivert.util.HashIntMap;
import com.samskivert.Log; import com.samskivert.Log;
/** /**
* Accomplishes the process of site identification based on a mapping from * Accomplishes the process of site identification based on a mapping from domains (e.g.
* domains (e.g. samskivert.com) to site identifiers that is maintained in * samskivert.com) to site identifiers that is maintained in a database table, accessible via JDBC
* a database table, accessible via JDBC (hence the name). * (hence the name).
* *
* <p> There are two tables, one that maps domains to site identifiers and * <p> There are two tables, one that maps domains to site identifiers and another that maps site
* another that maps site identifiers to site strings. These are both * identifiers to site strings. These are both loaded at construct time and refreshed periodically
* loaded at construct time and refreshed periodically in the course of * in the course of normal operation.
* normal operation.
* *
* <p> Note that any of the calls to identify, lookup or enumerate site * <p> Note that any of the calls to identify, lookup or enumerate site information can result in
* information can result in the sites table being refreshed from the * the sites table being refreshed from the database which will take relatively much longer than
* database which will take relatively much longer than the simple * the simple hashtable lookup that the operations normally require. However, this happens only
* hashtable lookup that the operations normally require. However, this * once every 15 minutes and the circumstances in which the site identifier are normally used can
* happens only once every 15 minutes and the circumstances in which the * generally accomodate the extra 100 milliseconds or so that it is likely to take to reload the
* site identifier are normally used can generally accomodate the extra * (tiny) sites and domains tables from the database.
* 100 milliseconds or so that it is likely to take to reload the (tiny)
* sites and domains tables from the database.
*/ */
public class JDBCTableSiteIdentifier implements SiteIdentifier public class JDBCTableSiteIdentifier implements SiteIdentifier
{ {
/** The database identifier used to obtain a connection from our /** The database identifier used to obtain a connection from our connection provider. The value
* connection provider. The value is <code>sitedb</code> which you'll * is <code>sitedb</code> which you'll probably need to know to provide the proper
* probably need to know to provide the proper configuration to your * configuration to your connection provider. */
* connection provider. */
public static final String SITE_IDENTIFIER_IDENT = "sitedb"; public static final String SITE_IDENTIFIER_IDENT = "sitedb";
/** /**
* Constructs a JDBC table site identifier with the supplied * Constructs a JDBC table site identifier with the supplied connection provider from which to
* connection provider from which to obtain its database connection. * obtain its database connection.
* *
* @see #SITE_IDENTIFIER_IDENT * @see #SITE_IDENTIFIER_IDENT
*/ */
@@ -89,6 +85,12 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
// documentation inherited // documentation inherited
public int identifySite (HttpServletRequest req) public int identifySite (HttpServletRequest req)
{ {
// check whether our site id was overridden
Integer override = (Integer)req.getAttribute(SITE_ID_OVERRIDE_KEY);
if (override != null) {
return override;
}
checkReloadSites(); checkReloadSites();
String serverName = req.getServerName(); String serverName = req.getServerName();
@@ -131,7 +133,6 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
/** /**
* Insert a new site into the site table and into this mapping. * Insert a new site into the site table and into this mapping.
*/ */
@SuppressWarnings("unchecked")
public Site insertNewSite (String siteString) public Site insertNewSite (String siteString)
throws PersistenceException throws PersistenceException
{ {
@@ -144,11 +145,11 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
site.siteString = siteString; site.siteString = siteString;
_repo.insertNewSite(site); _repo.insertNewSite(site);
// add it to our two mapping tables, taking care to avoid causing // add it to our two mapping tables, taking care to avoid causing enumerateSites() to choke
// enumerateSites() to choke @SuppressWarnings("unchecked") HashMap<String,Site> newStrings =
HashMap<String,Site> newStrings = (HashMap<String,Site>) (HashMap<String,Site>)_sitesByString.clone();
_sitesByString.clone(); @SuppressWarnings("unchecked") HashIntMap<Site> newIds =
HashIntMap<Site> newIds = (HashIntMap<Site>)_sitesById.clone(); (HashIntMap<Site>)_sitesById.clone();
newIds.put(site.siteId, site); newIds.put(site.siteId, site);
newStrings.put(site.siteString, site); newStrings.put(site.siteString, site);
_sitesByString = newStrings; _sitesByString = newStrings;
@@ -158,8 +159,7 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
} }
/** /**
* Checks to see if we should reload our sites information from the * Checks to see if we should reload our sites information from the sites table.
* sites table.
*/ */
protected void checkReloadSites () protected void checkReloadSites ()
{ {
@@ -221,15 +221,13 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
rs = stmt.executeQuery(query); rs = stmt.executeQuery(query);
ArrayList<SiteMapping> mappings = new ArrayList<SiteMapping>(); ArrayList<SiteMapping> mappings = new ArrayList<SiteMapping>();
while (rs.next()) { while (rs.next()) {
mappings.add(new SiteMapping(rs.getInt(2), mappings.add(new SiteMapping(rs.getInt(2), rs.getString(1)));
rs.getString(1)));
} }
// sort the mappings in order of specificity // sort the mappings in order of specificity
Collections.sort(mappings); Collections.sort(mappings);
_mappings = mappings; _mappings = mappings;
// Log.info("Loaded site mappings " + // Log.info("Loaded site mappings " + StringUtil.toString(_mappings) + ".");
// StringUtil.toString(_mappings) + ".");
// nothing to return // nothing to return
return null; return null;
@@ -251,12 +249,10 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
{ {
PreparedStatement stmt = null; PreparedStatement stmt = null;
try { try {
stmt = conn.prepareStatement( stmt = conn.prepareStatement("insert into sites (siteString) VALUES (?)");
"insert into sites (siteString) VALUES (?)");
stmt.setString(1, site.siteString); stmt.setString(1, site.siteString);
if (1 != stmt.executeUpdate()) { if (1 != stmt.executeUpdate()) {
throw new PersistenceException( throw new PersistenceException("Not inserted " + site);
"Not inserted " + site);
} }
site.siteId = liaison.lastInsertedId(conn); site.siteId = liaison.lastInsertedId(conn);
@@ -291,8 +287,7 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
} }
/** /**
* Site mappings sort from most specific (www.yahoo.com) to least * Site mappings sort from most specific (www.yahoo.com) to least specific (yahoo.com).
* specific (yahoo.com).
*/ */
public int compareTo (SiteMapping other) public int compareTo (SiteMapping other)
{ {
@@ -308,23 +303,18 @@ public class JDBCTableSiteIdentifier implements SiteIdentifier
protected String _rdomain; protected String _rdomain;
} }
/** The repository through which we load up site identifier /** The repository through which we load up site identifier information. */
* information. */
protected SiteIdentifierRepository _repo; protected SiteIdentifierRepository _repo;
/** The list of domain to site identifier mappings ordered from most /** The list of domain to site identifier mappings ordered from most specific domain to least
* specific domain to least specific. */ * specific. */
protected volatile ArrayList<SiteMapping> _mappings = protected volatile ArrayList<SiteMapping> _mappings = new ArrayList<SiteMapping>();
new ArrayList<SiteMapping>();
/** The mapping from integer site identifiers to string site /** The mapping from integer site identifiers to string site identifiers. */
* identifiers. */
protected volatile HashIntMap<Site> _sitesById = new HashIntMap<Site>(); protected volatile HashIntMap<Site> _sitesById = new HashIntMap<Site>();
/** The mapping from string site identifiers to integer site /** The mapping from string site identifiers to integer site identifiers. */
* identifiers. */ protected volatile HashMap<String,Site> _sitesByString = new HashMap<String,Site>();
protected volatile HashMap<String,Site> _sitesByString =
new HashMap<String,Site>();
/** Used to periodically reload our site data. */ /** Used to periodically reload our site data. */
protected long _lastReload; protected long _lastReload;
@@ -24,57 +24,56 @@ import java.util.Iterator;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
* Responsible for determining the unique site identifier based on * Responsible for determining the unique site identifier based on information available in the
* information available in the HTTP request. Site identifiers are * HTTP request. Site identifiers are integers ranging from 1 to {@link Integer#MAX_VALUE}. Because
* integers ranging from 1 to {@link Integer#MAX_VALUE}. Because the site * the site identifier implementation is likely to have access to the site classification metadata,
* identifier implementation is likely to have access to the site * this interface is also used to map integer site identifiers to string site identifiers.
* classification metadata, this interface is also used to map integer
* site identifiers to string site identifiers.
*/ */
public interface SiteIdentifier public interface SiteIdentifier
{ {
/** The default site identifier, to be used when a site cannot be /** The default site identifier, to be used when a site cannot be identified or for site
* identified or for site identifiers that don't wish to distinguish * identifiers that don't wish to distinguish between sites. */
* between sites. */
public static final int DEFAULT_SITE_ID = -1; public static final int DEFAULT_SITE_ID = -1;
/** The string identifier for the default site. */ /** The string identifier for the default site. */
public static final String DEFAULT_SITE_STRING = "default"; public static final String DEFAULT_SITE_STRING = "default";
/** Use this to override the site identification process by calling {@link
* HttpServletRequest#setAttribute} with this key and an Integer value indicating the site id
* to be used, and any call to {@link #identifySite} on that request will return the overridden
* site. */
public static final String SITE_ID_OVERRIDE_KEY = "SiteIdentifierOverride";
/** /**
* Returns the unique identifier for the site on which this request * Returns the unique identifier for the site on which this request originated. That may be
* originated. That may be divined by looking at the server name, or * divined by looking at the server name, or perhaps a request parameter, or part of the path
* perhaps a request parameter, or part of the path info. The * info. The mechanism (or mechanisms) are up to the implementation. Note: the implementation
* mechanism (or mechanisms) are up to the implementation. * must honor the {@link #SITE_ID_OVERRIDE_KEY} request attribute.
* *
* @param req the http servlet request the site for which we are * @param req the http servlet request the site for which we are trying to identify.
* trying to identify.
* *
* @return the unique site identifier requestsed or {@link * @return the unique site identifier requestsed or {@link #DEFAULT_SITE_ID} if the site could
* #DEFAULT_SITE_ID} if the site could not be identified. No site * not be identified. No site should ever have a site id value of 0.
* should ever have a site id value of 0.
*/ */
public int identifySite (HttpServletRequest req); public int identifySite (HttpServletRequest req);
/** /**
* Returns a string representation of the site identifier. The * Returns a string representation of the site identifier. The SiteIdentifier in use can map
* SiteIdentifier in use can map the site ids to strings however it * the site ids to strings however it likes as long as it consistently maps the same identifier
* likes as long as it consistently maps the same identifier to the * to the same string and vice versa. Presumably these strings would be human readable and
* same string and vice versa. Presumably these strings would be human * meaningful.
* readable and meaningful.
* *
* @param siteId the unique integer identifier for the site that we * @param siteId the unique integer identifier for the site that we wish to be identified by a
* wish to be identified by a string. * string.
* *
* @return the string identifier for this site. * @return the string identifier for this site.
*/ */
public String getSiteString (int siteId); public String getSiteString (int siteId);
/** /**
* Returns the site identifier for the site associated with the * Returns the site identifier for the site associated with the supplied site string. The
* supplied site string. The SiteIdentifier in use can map the site * SiteIdentifier in use can map the site ids to strings however it likes as long as it
* ids to strings however it likes as long as it consistently maps the * consistently maps the same string to the same identifier and vice versa.
* same string to the same identifier and vice versa.
* *
* @param siteString the string to be converted into a site identifer. * @param siteString the string to be converted into a site identifer.
* *
@@ -83,8 +82,7 @@ public interface SiteIdentifier
public int getSiteId (String siteString); public int getSiteId (String siteString);
/** /**
* Returns an enumerator over all {@link Site} mappings known to this * Returns an enumerator over all {@link Site} mappings known to this SiteIdentifier.
* SiteIdentifier.
*/ */
public Iterator<Site> enumerateSites (); public Iterator<Site> enumerateSites ();
} }