From 44d534a2c0bf4409e3f293e26c95689f6011c1df Mon Sep 17 00:00:00 2001 From: mdb Date: Thu, 1 Nov 2001 21:34:19 +0000 Subject: [PATCH] Created a site identifier that reads data from a JDBC table. git-svn-id: https://samskivert.googlecode.com/svn/trunk@410 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../servlet/JDBCTableSiteIdentifier.java | 199 ++++++++++++++++++ .../src/sql/create_site_tables.mysql | 25 +++ 2 files changed, 224 insertions(+) create mode 100644 projects/samskivert/src/java/com/samskivert/servlet/JDBCTableSiteIdentifier.java create mode 100644 projects/samskivert/src/sql/create_site_tables.mysql diff --git a/projects/samskivert/src/java/com/samskivert/servlet/JDBCTableSiteIdentifier.java b/projects/samskivert/src/java/com/samskivert/servlet/JDBCTableSiteIdentifier.java new file mode 100644 index 00000000..50af1f7a --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/servlet/JDBCTableSiteIdentifier.java @@ -0,0 +1,199 @@ +// +// $Id: JDBCTableSiteIdentifier.java,v 1.1 2001/11/01 21:34:19 mdb Exp $ +// +// samskivert library - useful routines for java programs +// Copyright (C) 2001 Michael Bayne +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.samskivert.servlet; + +import java.sql.Connection; +import java.sql.Statement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import java.util.ArrayList; +import javax.servlet.http.HttpServletRequest; +import com.samskivert.io.PersistenceException; + +import com.samskivert.jdbc.ConnectionProvider; +import com.samskivert.jdbc.DatabaseLiaison; +import com.samskivert.jdbc.SimpleRepository; +import com.samskivert.jdbc.JDBCUtil; +import com.samskivert.util.HashIntMap; + +/** + * Accomplishes the process of site identification based on a mapping from + * domains (e.g. samskivert.com) to site identifiers that is maintained in + * a database table, accessible via JDBC (hence the name). + * + *

There are two tables, one that maps domains to site identifiers and + * another that maps site identifiers to site strings. These are both + * loaded at construct time and refreshed periodically in the course of + * normal operation. + */ +public class JDBCTableSiteIdentifier implements SiteIdentifier +{ + /** The database identifier used to obtain a connection from our + * connection provider. The value is sitedb which you'll + * probably need to know to provide the proper configuration to your + * connection provider. */ + public static final String SITE_IDENTIFIER_IDENT = "sitedb"; + + /** + * Constructs a JDBC table site identifier with the supplied + * connection provider from which to obtain its database connection. + * + * @see #SITE_IDENTIFIER_IDENT + */ + public JDBCTableSiteIdentifier (ConnectionProvider conprov) + throws PersistenceException + { + _repo = new SiteIdentifierRepository(conprov); + // load up our site data + _repo.refreshSiteData(); + } + + // documentation inherited + public int identifySite (HttpServletRequest req) + { + String serverName = req.getServerName(); + + // scan for the mapping that matches the specified domain + int msize = _mappings.size(); + for (int i = 0; i < msize; i++) { + SiteMapping mapping = (SiteMapping)_mappings.get(i); + if (serverName.endsWith(mapping.domain)) { + return mapping.siteId; + } + } + + // if we matched nothing, return the default id + return DEFAULT_SITE_ID; + } + + // documentation inherited + public String getSiteString (int siteId) + { + String stringId = (String)_sites.get(siteId); + return (stringId == null) ? DEFAULT_SITE_STRING : stringId; + } + + /** + * Used to load information from the site database. + */ + protected class SiteIdentifierRepository + extends SimpleRepository implements SimpleRepository.Operation + { + public SiteIdentifierRepository (ConnectionProvider conprov) + { + super(conprov, SITE_IDENTIFIER_IDENT); + } + + public void refreshSiteData () + throws PersistenceException + { + // we are the operation! + execute(this); + } + + public Object invoke (Connection conn, DatabaseLiaison liaison) + throws PersistenceException, SQLException + { + Statement stmt = conn.createStatement(); + try { + // first load up the list of sites + String query = "select siteId, stringId from sites"; + ResultSet rs = stmt.executeQuery(query); + HashIntMap sites = new HashIntMap(); + while (rs.next()) { + sites.put(rs.getInt(1), rs.getString(2)); + } + _sites = sites; + + // now load up the domain mappings + query = "select domain, siteId from sites"; + rs = stmt.executeQuery(query); + ArrayList mappings = new ArrayList(); + while (rs.next()) { + SiteMapping mapping = new SiteMapping(); + mapping.domain = rs.getString(1); + mapping.siteId = rs.getInt(2); + mappings.add(mapping); + } + _mappings = mappings; + + // nothing to return + return null; + + } finally { + JDBCUtil.close(stmt); + } + } + } + + /** + * Used to track domain to site identifier mappings. + */ + protected static class SiteMapping implements Comparable + { + /** The domain to match. */ + public String domain; + + /** The site identifier for the associated domain. */ + public int siteId; + + /** + * Site mappings sort from most specific (www.yahoo.com) to least + * specific (yahoo.com). + */ + public int compareTo (Object other) + { + if (other instanceof SiteMapping) { + SiteMapping orec = (SiteMapping)other; + + // if the domains are equal, we're equal + if (domain.equals(orec.domain)) { + return 0; + + } else if (domain.endsWith(orec.domain)) { + // if our domain is a subset of their domain, they are + // after us + return 1; + + } else { + return -1; + } + + } else { + // no comparablo + return -1; + } + } + } + + /** The repository through which we load up site identifier + * information. */ + protected SiteIdentifierRepository _repo; + + /** The list of domain to site identifier mappings ordered from most + * specific domain to least specific. */ + protected ArrayList _mappings = new ArrayList(); + + /** The mapping from integer site identifiers to string site + * identifiers. */ + protected HashIntMap _sites = new HashIntMap(); +} diff --git a/projects/samskivert/src/sql/create_site_tables.mysql b/projects/samskivert/src/sql/create_site_tables.mysql new file mode 100644 index 00000000..c5b91ab2 --- /dev/null +++ b/projects/samskivert/src/sql/create_site_tables.mysql @@ -0,0 +1,25 @@ +/** + * $Id: create_site_tables.mysql,v 1.1 2001/11/01 21:34:19 mdb Exp $ + * + * Creates the necessary database tables in MySQL for the JDBC table site + * identifier. + */ + +/** + * The sites table contains a row for every site, along with its human + * readable name identifier. + */ +DROP TABLE IF EXISTS sites; +CREATE TABLE sites ( + siteId INTEGER(5) PRIMARY KEY NOT NULL AUTO_INCREMENT, + stringId VARCHAR(24) NOT NULL +); + +/** + * The domains table contains a row for every domain to site mapping. + */ +DROP TABLE IF EXISTS domains; +CREATE TABLE domains ( + domain VARCHAR(128) PRIMARY KEY NOT NULL, + siteId INTEGER(5) NOT NULL +);