Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java	(revision 28983)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java	(revision 28984)
@@ -69,11 +69,8 @@
 	/** database type : gdbm, jdbm or sqlite */
 	protected String db_type = "";
-
-	/** does this collection provide the OAI service */
-	protected boolean has_oai = false;
-	/** time when this collection was built */
+	/** time when this collection was built Used by RSS */
 	protected long lastmodified = 0;
-	/** earliestDatestamp of this collection. Necessary for OAI */
-	protected long earliestDatestamp = 0;
+	/** earliestDatestamp of this collection. Used by OAI/RSS */
+        protected long earliestDatestamp = 0;
 
 	/** Stores the default accessibility of guest users */
@@ -174,5 +171,5 @@
 	}
 
-	// Used by OAI Receptionist to determine whether to expire a resumption token - if a token was issued before a collection is rebuilt, then the token must be expired.
+	// Used by OAI Receptionist and RSSRetrieve 
 	public long getLastmodified()
 	{
@@ -180,17 +177,8 @@
 	}
 
-	// used by the OAIReceptionist to find out the earliest datestamp amongst all oai collections in the repository
+	// used by the OAIReceptionist and RSSRetrieve
 	public long getEarliestDatestamp()
 	{
 		return earliestDatestamp;
-	}
-
-	/**
-	 * whether the service_map in ServiceCluster.java contains the service
-	 * 'OAIPMH' 11/06/2007 xiao
-	 */
-	public boolean hasOAI()
-	{
-		return has_oai;
 	}
 
@@ -248,17 +236,6 @@
 	protected boolean findAndLoadInfo(Element coll_config_xml, Element build_config_xml)
 	{
-		// Element meta_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
-		// addMetadata(meta_list);
-		// meta_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
-		// addMetadata(meta_list);
-		addMetadata("httpPath", this.site_http_address + "/collect/" + this.cluster_name);
-
-		// display stuff
-		// Element display_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
-		// if (display_list != null)
-		// {
-		// 	resolveMacros(display_list);
-		// 	addDisplayItems(display_list);
-		// }
+	  addMetadata("httpPath", this.site_http_address + "/collect/" + this.cluster_name);
+
 
 		//check whether the html are tidy or not
@@ -285,7 +262,8 @@
 		addMetadata("tidyoption", tidy);
 
-		// check whether we are public or not
+		
 		if (this.metadata_list != null)
 		{
+		  // check whether we are public or not
 			Element meta_elem = (Element) GSXML.getNamedElement(this.metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public");
 			if (meta_elem != null)
@@ -297,4 +275,13 @@
 				}
 			}
+			// earliest datestamp is the time the collection was created.
+			meta_elem = (Element) GSXML.getNamedElement(this.metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, OAIXML.EARLIEST_DATESTAMP);
+			if (meta_elem != null) {
+			  String earliestDatestampStr = GSXML.getValue(meta_elem);
+			  if (!earliestDatestampStr.equals("")) {
+			      earliestDatestamp = Long.parseLong(earliestDatestampStr) * 1000; // stored in seconds, convert to milliseconds
+			  }
+			}
+		
 		}
 		return true;
@@ -393,9 +380,7 @@
 		clearServices();
 		Element service_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
-		Element oai_service_rack = null;
 		if (service_list != null)
 		{
 			configureServiceRackList(service_list, coll_config_xml);
-			oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, GSXML.NAME_ATT, OAIXML.OAIPMH);
 		}
 		// collection Config may also contain manually added service racks
@@ -404,41 +389,5 @@
 		{
 			configureServiceRackList(service_list, build_config_xml);
-			// this oai used in preference to one in buildConfig.xml
-			oai_service_rack = GSXML.getNamedElement(service_list, GSXML.SERVICE_CLASS_ELEM, GSXML.NAME_ATT, OAIXML.OAIPMH);
-		}
-		// Check for oai
-
-		if (oai_service_rack != null)
-		{
-			has_oai = true;
-			logger.info(this.cluster_name + " has OAI services");
-			// extract earliestDatestamp from the buildconfig.xml for OAI
-			Element metadata_list = (Element) GSXML.getChildByTagName(build_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
-
-			if (metadata_list != null)
-			{
-				NodeList children = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
-				// can't do getChildNodes(), because whitespace, such as newlines, creates Text nodes
-				for (int i = 0; i < children.getLength(); i++)
-				{
-					Element metadata = (Element) children.item(i);
-					if (metadata.getAttribute(GSXML.NAME_ATT).equals(OAIXML.EARLIEST_DATESTAMP))
-					{
-						String earliestDatestampStr = GSXML.getValue(metadata);
-						if (!earliestDatestampStr.equals(""))
-						{
-						  earliestDatestamp = Long.parseLong(earliestDatestampStr) * 1000; // stored in seconds, convert to milliseconds
-							
-						}
-						break; // found a metadata element with name=earliestDatestamp in buildconfig
-					}
-				}
-			}
-
-			// If at the end of this, there is no value for earliestDatestamp, print out a warning
-			logger.warn("No earliestDatestamp in buildConfig.xml for collection: " + this.cluster_name + ". Defaulting to 0.");
-
-		} // if oai_service_rack != null
-
+		}
 		return true;
 	}
Index: /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/OAICollection.java
===================================================================
--- /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/OAICollection.java	(revision 28984)
+++ /main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/OAICollection.java	(revision 28984)
@@ -0,0 +1,198 @@
+/*
+ *    Collection.java
+ *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program 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 General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.greenstone.gsdl3.collection;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import org.greenstone.gsdl3.core.ModuleInterface;
+import org.greenstone.gsdl3.service.ServiceRack;
+import org.greenstone.gsdl3.util.GSFile;
+import org.greenstone.gsdl3.util.GSXML;
+import org.greenstone.gsdl3.util.GSXSLT;
+import org.greenstone.gsdl3.util.OAIXML;
+import org.greenstone.gsdl3.util.SimpleMacroResolver;
+import org.greenstone.gsdl3.util.UserContext;
+import org.greenstone.gsdl3.util.XMLConverter;
+import org.greenstone.gsdl3.util.XMLTransformer;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Represents a collection for the OAI server. This is a cut down version of Collection, as we
+ * only want to load the OAIPMH service rack, not any of the others
+ * 
+ * @author Katherine Don
+ * @see ModuleInterface
+ */
+public class OAICollection extends Collection
+{
+
+	static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.OAICollection.class.getName());
+
+	/** does this collection provide the OAI service */
+	protected boolean has_oai = false;
+
+	/**
+	 * Configures the collection.
+	 * 
+	 * site_home and cluster_name  must be set before configure is called.
+	 * 
+	 * collection metadata is obtained, and services loaded.
+	 * 
+	 * @return true/false on success/fail
+	 */
+	public boolean configure()
+	{
+		if (this.site_home == null || this.cluster_name == null)
+		{
+			logger.error("Collection: site_home and collection_name must be set before configure called!");
+			return false;
+		}
+
+		macro_resolver.addMacro("_httpcollection_", this.site_http_address + "/collect/" + this.cluster_name);
+
+		Element coll_config_xml = loadCollConfigFile();
+		GSXSLT.modifyCollectionConfigForDebug(coll_config_xml);
+		Element build_config_xml = loadBuildConfigFile();
+
+		if (coll_config_xml == null || build_config_xml == null)
+		{
+			return false;
+		}
+
+		// process the metadata and display items and default library params
+		super.configureLocalData(coll_config_xml);
+		super.configureLocalData(build_config_xml);
+		// get extra collection specific stuff
+		findAndLoadInfo(coll_config_xml, build_config_xml);
+
+		// load up the OAIPMH serviceRack
+		configureServiceRacks(coll_config_xml, build_config_xml);
+
+		return true;
+
+	}
+
+
+	/**
+	 * whether this collection has OAIPMH services
+	 */
+	public boolean hasOAI()
+	{
+		return has_oai;
+	}
+
+
+
+  /** override this to only load up OAIPMH serviceRack  - don't need all the rest of them for oai*/
+	protected boolean configureServiceRackList(Element service_rack_list, Element extra_info)
+	{
+
+	  // find the OAIPMH service
+	  Element oai_service_xml = GSXML.getNamedElement(service_rack_list, GSXML.SERVICE_CLASS_ELEM, GSXML.NAME_ATT, OAIXML.OAI_SERVICE_RACK);
+	  if (oai_service_xml == null) {
+	    return false;
+	  }
+	  
+	  // the xml request to send to the serviceRack to query what services it provides
+	  Document doc = XMLConverter.newDOM();
+	  Element message = doc.createElement(GSXML.MESSAGE_ELEM);
+	  Element request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
+	  message.appendChild(request);
+
+	  ServiceRack s = null;
+	  
+	  try {
+	    
+	    // try for a default service in standard package
+	    s = (ServiceRack) Class.forName("org.greenstone.gsdl3.service." + OAIXML.OAI_SERVICE_RACK).newInstance();
+	    
+	  } catch (Exception e) {}
+	    
+	  if (s == null) {
+	    
+	    try {
+	      // name as is, in case package is already specified
+	      s = (ServiceRack) Class.forName(OAIXML.OAI_SERVICE_RACK).newInstance();
+	    } catch (Exception e) {}
+	  }
+
+	  if (s == null) {
+	    
+	    logger.error("Couldn't get an instance of class " + OAIXML.OAI_SERVICE_RACK + ", or org.greenstone.gsdl3.service." + OAIXML.OAI_SERVICE_RACK);
+	    return false;
+	  }
+
+
+	  s.setSiteHome(this.site_home);
+	  s.setSiteAddress(this.site_http_address);
+	  s.setClusterName(this.cluster_name);
+	  s.setServiceCluster(this);
+	  s.setMessageRouter(this.router);
+	  // pass the xml node to the service for configuration
+	  if (s.configure(oai_service_xml, extra_info)) {
+	    
+	    // find out the supported service types for this service module
+	    Node types = s.process(message);
+	    NodeList typenodes = ((Element) types).getElementsByTagName(GSXML.SERVICE_ELEM);
+	    
+	    for (int j = 0; j < typenodes.getLength(); j++)
+	      {
+		String service = ((Element) typenodes.item(j)).getAttribute(GSXML.NAME_ATT);
+		
+		if (service_map.get(service) != null)
+		  {
+		    char extra = '0';
+		    String new_service = service + extra;
+		    
+		    while (service_map.get(new_service) != null)
+		      {
+			extra++;
+			new_service = service + extra;
+		      }
+		    this.service_name_map.put(new_service, service);
+		    service = new_service;
+		    ((Element) typenodes.item(j)).setAttribute(GSXML.NAME_ATT, service);
+		  }
+		this.service_map.put(service, s);
+		// also add info to the ServiceInfo XML element
+		this.service_list.appendChild(this.desc_doc.importNode(typenodes.item(j), true));
+	      }
+	    has_oai = true;
+	    return true;
+	  }
+	  
+
+	  return false;
+	}
+
+}
