Index: lib/web.xml.tomcat5
===================================================================
--- lib/web.xml.tomcat5	(revision 6263)
+++ lib/web.xml.tomcat5	(revision 6264)
@@ -179,7 +179,7 @@
       <load-on-startup>10</load-on-startup>
     </servlet>
     
-<!-- CN REST Servlet -->
+	<!-- CN REST Servlet -->
     <servlet>
       <servlet-name>CNRestServlet</servlet-name>
       <servlet-class>edu.ucsb.nceas.metacat.restservice.CNRestServlet</servlet-class>
@@ -192,7 +192,22 @@
         <param-value>true</param-value>
       </init-param>
       <load-on-startup>15</load-on-startup>
-    </servlet>    
+    </servlet>
+    
+    <!-- MN REST Servlet -->
+    <servlet>
+      <servlet-name>MNRestServlet</servlet-name>
+      <servlet-class>edu.ucsb.nceas.metacat.restservice.MNRestServlet</servlet-class>
+      <init-param>
+        <param-name>debug</param-name>
+        <param-value>1</param-value>
+      </init-param>
+      <init-param>
+        <param-name>listings</param-name>
+        <param-value>true</param-value>
+      </init-param>
+      <load-on-startup>20</load-on-startup>
+    </servlet>
   
     <servlet-mapping>
         <servlet-name>metacat</servlet-name>
@@ -305,11 +320,6 @@
     <url-pattern>/d1/monitor/*</url-pattern>
   </servlet-mapping>
 
-  <servlet-mapping>
-    <servlet-name>RestServlet</servlet-name>
-    <url-pattern>/d1/*</url-pattern>
-  </servlet-mapping>
-
 	<!-- CN REST services -->
 	<!-- CNCore-->
 	<servlet-mapping>
@@ -372,6 +382,52 @@
 		<url-pattern>/d1/cn/meta/policy/*</url-pattern>
 	</servlet-mapping>
 	
+	<!-- MN REST services -->
+	<!-- MNCore-->
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/monitor/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/log/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/node</url-pattern>
+	</servlet-mapping>
+	<!-- MNRead-->
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/meta/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/object/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/checksum/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/error</url-pattern>
+	</servlet-mapping>
+	<!-- MNAuthorization -->
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/isAuthorized/*</url-pattern>
+	</servlet-mapping>
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/accessRules/*</url-pattern>
+	</servlet-mapping>
+	<!-- MNReplication -->
+	<servlet-mapping>
+		<servlet-name>MNRestServlet</servlet-name>
+		<url-pattern>/d1/mn/replicate/*</url-pattern>
+	</servlet-mapping>
+	
 
  <!-- uncomment this if you want the admin servlet -->
   <servlet-mapping>
Index: src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java	(nonexistent)
+++ src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java	(revision 6264)
@@ -0,0 +1,1226 @@
+/**
+ *  '$RCSfile$'
+ *  Copyright: 2011 Regents of the University of California and the
+ *              National Center for Ecological Analysis and Synthesis
+ *
+ *   '$Author$'
+ *     '$Date$'
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+package edu.ucsb.nceas.metacat.restservice;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.dataone.client.ObjectFormatCache;
+import org.dataone.client.auth.CertificateManager;
+import org.dataone.mimemultipart.MultipartRequest;
+import org.dataone.mimemultipart.MultipartRequestResolver;
+import org.dataone.service.exceptions.BaseException;
+import org.dataone.service.exceptions.IdentifierNotUnique;
+import org.dataone.service.exceptions.InsufficientResources;
+import org.dataone.service.exceptions.InvalidRequest;
+import org.dataone.service.exceptions.InvalidSystemMetadata;
+import org.dataone.service.exceptions.InvalidToken;
+import org.dataone.service.exceptions.NotAuthorized;
+import org.dataone.service.exceptions.NotFound;
+import org.dataone.service.exceptions.NotImplemented;
+import org.dataone.service.exceptions.ServiceFailure;
+import org.dataone.service.exceptions.SynchronizationFailed;
+import org.dataone.service.exceptions.UnsupportedType;
+import org.dataone.service.types.AccessPolicy;
+import org.dataone.service.types.Checksum;
+import org.dataone.service.types.DescribeResponse;
+import org.dataone.service.types.Event;
+import org.dataone.service.types.Identifier;
+import org.dataone.service.types.Log;
+import org.dataone.service.types.MonitorList;
+import org.dataone.service.types.Node;
+import org.dataone.service.types.NodeList;
+import org.dataone.service.types.NodeReference;
+import org.dataone.service.types.ObjectFormat;
+import org.dataone.service.types.ObjectList;
+import org.dataone.service.types.Permission;
+import org.dataone.service.types.Subject;
+import org.dataone.service.types.SystemMetadata;
+import org.jibx.runtime.JiBXException;
+
+import edu.ucsb.nceas.metacat.MetacatHandler;
+import edu.ucsb.nceas.metacat.dataone.MNodeService;
+
+/**
+ * MN REST service implementation handler
+ * 
+ * ******************
+ * MNCore -- DONE
+ * 		ping() - GET /d1/mn/monitor/ping
+ * 		log() - GET /d1/mn/log
+ * 		**getObjectStatistics() - GET /d1/mn/monitor/object
+ * 		getOperationsStatistics - GET /d1/mn/monitor/event
+ * 		**getStatus - GET /d1/mn/monitor/status
+ * 		getCapabilities() - GET /d1/mn/ and /d1/mn/node
+ * 	
+ * 	MNRead -- DONE
+ * 		get() - GET /d1/mn/object/PID
+ * 		getSystemMetadata() - GET /d1/mn/meta/PID
+ * 		describe() - HEAD /d1/mn/object/PID
+ * 		getChecksum() - GET /d1/mn/checksum/PID
+ * 		listObjects() - GET /d1/mn/object
+ * 		synchronizationFailed() - POST /d1/mn/error
+ * 	
+ * 	MNAuthorization -- DONE
+ * 		isAuthorized() - GET /d1/mn/isAuthorized/PID
+ * 		setAccessPolicy() - PUT /d1/mn/accessRules/PID
+ * 		
+ * 	MNStorage
+ * 		create() - POST /d1/mn/object/PID
+ * 		update() - PUT /d1/mn/object/PID
+ * 		delete() - DELETE /d1/mn/object/PID
+ * 	
+ * 	MNReplication
+ * 		replicate() - POST /d1/mn/replicate
+ * 
+ * ******************
+ * @author leinfelder
+ *
+ */
+public class MNResourceHandler extends ResourceHandler{
+
+    // MN-specific API Resources
+    protected static final String RESOURCE_MONITOR = "monitor";
+    protected static final String RESOURCE_REPLICATE = "replicate";
+    protected static final String RESOURCE_NODE = "node";
+    protected static final String RESOURCE_ERROR = "error";
+
+
+    /**
+     * Initializes new instance by setting servlet context,request and response
+     * */
+    public MNResourceHandler(ServletContext servletContext,
+            HttpServletRequest request, HttpServletResponse response) {
+    	super(servletContext, request, response);
+        logMetacat = Logger.getLogger(MNResourceHandler.class);
+    }
+
+    /**
+     * This function is called from REST APU servlet and handles each request to the servlet 
+     * 
+     * @param httpVerb (GET, POST, PUT or DELETE)
+     */
+    public void handle(byte httpVerb) {
+        logMetacat = Logger.getLogger(MNResourceHandler.class);
+        try {
+            String resourcePrefix = RESOURCE_BASE_URL + "/mn/";
+        	String resource = request.getServletPath();
+            
+            if (resource.endsWith(resourcePrefix)) {
+                resource = RESOURCE_NODE;
+            }
+            else {
+            	// remove prefix
+                resource = resource.substring(resource.indexOf(resourcePrefix) + resourcePrefix.length());
+                resource = resource.trim();
+            }
+                        
+            System.out.println("handling verb " + httpVerb + " request with resource '" + resource + "'");
+            System.out.println("resource: '" + resource + "'");
+            boolean status = false;
+
+            // load session from certificate in request
+            session = CertificateManager.getInstance().getSession(request);
+            
+            if (resource != null) {
+                //resource = request.getServletPath().substring(1);
+
+                params = new Hashtable<String, String[]>();
+                initParams();
+
+                Timer timer = new Timer();
+                handler = new MetacatHandler(timer);
+
+                if (resource.equals(RESOURCE_NODE)) {
+                    // node response
+                    node();
+                    status = true;
+                    
+                } else if (resource.equals(RESOURCE_ACCESS_RULES)) {
+                    if (httpVerb == POST) {
+	                	// set the access rules
+	                    setaccess();
+	                    status = true;
+	                    System.out.println("done setting access");
+                    }
+                } else if (resource.equals(RESOURCE_IS_AUTHORIZED)) {
+                    if (httpVerb == GET) {
+	                	// check the access rules
+                    	String objectId = request.getPathInfo();
+                        if (objectId != null && objectId.length() > 1) {
+                            objectId = request.getPathInfo().substring(1);
+                        }
+	                    isAuthorized(objectId);
+	                    status = true;
+	                    System.out.println("done getting access");
+                    }
+                } else if (resource.equals(RESOURCE_META)) {
+                    System.out.println("Using resource 'meta'");
+                    String objectId = request.getPathInfo();
+                    if (objectId != null && objectId.length() > 1) {
+                        objectId = request.getPathInfo().substring(1);
+                    }
+                    
+                    // get
+                    if (httpVerb == GET) {
+                        getSystemMetadataObject(objectId);
+                        status = true;
+                    }
+                    
+                    // post to register system metadata
+                    if (httpVerb == POST) {
+                    	registerSystemMetadata(objectId);
+                    	status = true;
+                    }
+
+                } else if (resource.equals(RESOURCE_OBJECTS)) {
+                    System.out.println("Using resource 'object'");
+
+                    String objectId = request.getPathInfo();
+                    if (objectId != null && objectId.length() > 1) {
+                        objectId = request.getPathInfo().substring(1);
+                    } else {
+                        objectId = null;
+                    }
+                    
+                    System.out.println("objectId: " + objectId);
+                    logMetacat.debug("verb:" + httpVerb);
+
+                    if (httpVerb == GET) {
+                        getObject(objectId);
+                        status = true;
+                    } else if (httpVerb == POST) {
+                        putObject(objectId, FUNCTION_NAME_INSERT);
+                        status = true;
+                    } else if (httpVerb == PUT) {
+                        putObject(objectId, FUNCTION_NAME_UPDATE);
+                        status = true;
+                    } else if (httpVerb == DELETE) {
+                        deleteObject(objectId);
+                        status = true;
+                    } else if (httpVerb == HEAD) {
+                        describeObject(objectId);
+                        status = true;
+                    }
+                  
+                } else if (resource.equals(RESOURCE_LOG)) {
+                    System.out.println("Using resource 'log'");
+                    // handle log events
+                    if (httpVerb == GET) {
+                        getLog();
+                        status = true;
+                    }
+                } else if (resource.equals(RESOURCE_CHECKSUM)) {
+                    System.out.println("Using resource 'checksum'");
+                    // handle checksum requests
+                    if (httpVerb == GET) {
+                        checksum();
+                        status = true;
+                    }
+                } else if (resource.startsWith(RESOURCE_MONITOR)) {
+                    // there are various parts to monitoring
+                    if (httpVerb == GET) {
+                    	// health monitoring calls
+                        monitor();
+                    }
+                    status = true;
+                } else if (resource.equals(RESOURCE_REPLICATE)) {
+                	if (httpVerb == POST) {
+	                    System.out.println("processing replicate request");
+	                    replicate();
+	                    status = true;
+                	}
+                } else if (resource.equals(RESOURCE_ERROR)) {
+	                // sync error
+	                if (httpVerb == POST) {
+	                    syncError();
+	                    status = true;
+	                }
+                }
+                
+                if (!status) {
+                    response.setStatus(400);
+                    printError("Incorrect parameters!", response);
+                }
+            } else {
+                response.setStatus(400);
+                printError("Incorrect resource!", response);
+            }
+        } catch (BaseException be) {
+        	// report Exceptions as clearly as possible
+        	OutputStream out = null;
+			try {
+				out = response.getOutputStream();
+			} catch (IOException e) {
+				logMetacat.error("Could not get output stream from response", e);
+			}
+            serializeException(be, out);
+        } catch (Exception e) {
+            logMetacat.error(e.getClass() + ": " + e.getMessage());
+            System.out.println("Error in ResourceHandler.handle(): " + e.getClass() + ": " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+    
+    private boolean isAuthorized(String id) throws ServiceFailure, InvalidToken, NotFound, NotAuthorized, NotImplemented, InvalidRequest {
+		Identifier pid = new Identifier();
+		pid.setValue(id);
+		Permission permission = null;
+		try {
+			String perm = params.get("permission")[0];
+			permission = Permission.valueOf(perm);
+		} catch (Exception e) {
+			logMetacat.warn("No permission specified");
+		}
+		boolean result = MNodeService.getInstance().isAuthorized(session, pid, permission);
+		response.setStatus(200);
+		response.setContentType("text/xml");
+		return result;
+    }
+    
+    private void syncError() throws NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, UnsupportedEncodingException, JiBXException {
+    	SynchronizationFailed syncFailed = null;
+    	if (params.containsKey("message")) {
+            String message = params.get("message")[0];
+            syncFailed = (SynchronizationFailed) deserializeServiceType(SynchronizationFailed.class, new ByteArrayInputStream(message.getBytes("UTF-8")));
+        }
+		MNodeService.getInstance().synchronizationFailed(session, syncFailed);
+    }
+    
+    private boolean monitor() throws NotFound, ParseException, NotImplemented, ServiceFailure, NotAuthorized, InvalidRequest, InsufficientResources, UnsupportedType, IOException, JiBXException {
+    	System.out.println("processing monitor request");
+        String pathInfo = request.getPathInfo();
+        
+        System.out.println("verb is GET");
+        System.out.println("pathInfo is " + pathInfo);
+        pathInfo = pathInfo.substring(1);
+        
+        if (pathInfo.toLowerCase().equals("ping")) {
+            System.out.println("processing ping request");
+            boolean result = MNodeService.getInstance().ping();
+            return result;
+            
+        } else if (pathInfo.toLowerCase().equals("status")) {
+            System.out.println("processing status request");
+            // TODO: implement in MNCore
+            //MNodeService.getInstance().getStatus();
+            return false;
+            
+        } else if (pathInfo.toLowerCase().equals("object")) {
+            System.out.println("processing object request");
+            Identifier pid = null;
+            ObjectFormat format = null;
+            if (params.containsKey("format")) {
+                String f = params.get("format")[0];
+                format = ObjectFormatCache.getInstance().getFormat(f);
+            }
+            if (params.containsKey("pid")) {
+                String id = params.get("pid")[0];
+                pid = new Identifier();
+                pid.setValue(id);
+            }
+            
+            // TODO: implement in MNCore
+            //ObjectStatistics objectStats = MNodeService.getInstance().getObjectStatistics(format, pid);
+            
+        } else if (pathInfo.toLowerCase().equals("event")) {
+            System.out.println("processing event request");
+            ObjectFormat format = null;
+            Integer period = null;
+            String requestor = null;
+            Subject subject = null;
+            String eventName = null;
+            Event event = null;
+
+            if (params.containsKey("format")) {
+                String f = params.get("format")[0];
+                format = ObjectFormatCache.getInstance().getFormat(f);
+            }
+            if (params.containsKey("period")) {
+                String t = params.get("period")[0];
+                period = Integer.valueOf(t);
+            }
+            if (params.containsKey("requestor")) {
+            	requestor = params.get("requestor")[0];
+            	subject = new Subject();
+            	subject.setValue(requestor);
+            }
+            if (params.containsKey("event")) {
+            	eventName = params.get("event")[0];
+                event = Event.valueOf(eventName);
+            }
+            
+            MonitorList monitorList = MNodeService.getInstance().getOperationStatistics(session, period, subject, event, format);
+            
+            OutputStream out = response.getOutputStream();
+            response.setStatus(200);
+            response.setContentType("text/xml");
+            
+            serializeServiceType(MonitorList.class, monitorList, out);
+            
+        }
+        
+        return true;
+    }
+    
+    private void checksum() throws NotImplemented, JiBXException, IOException {
+    	String checksumAlgorithm = "MD5";
+        String guid = request.getPathInfo();
+        if (guid != null && guid.length() > 1) {
+            guid = request.getPathInfo().substring(1); // trim the slash
+        }
+        Identifier guidid = new Identifier();
+        guidid.setValue(guid);
+        try {
+            checksumAlgorithm = params.get("checksumAlgorithm")[0];
+        } catch(Exception e) {
+            //do nothing.  default to MD5
+        	logMetacat.warn("No algorithm specified, using default: " + checksumAlgorithm);
+        }
+        System.out.println("getting checksum for object " + guid + " with algorithm " + checksumAlgorithm);
+        try {
+            Checksum c = MNodeService.getInstance().getChecksum(session, guidid, checksumAlgorithm);
+            System.out.println("got checksum " + c.getValue());
+            response.setStatus(200);
+            System.out.println("serializing response");
+            serializeServiceType(Checksum.class, c, response.getOutputStream());
+            System.out.println("done serializing response.");
+        }
+        catch(NotAuthorized na)
+        {
+            na.setDetail_code("1400");
+            serializeException(na, response.getOutputStream());
+        }
+        catch(NotFound nf)
+        {
+            nf.setDetail_code("1420");
+            serializeException(nf, response.getOutputStream());
+        }
+        catch(InvalidRequest ir)
+        {
+            ir.setDetail_code("1402");
+            serializeException(ir, response.getOutputStream());
+        }
+        catch(ServiceFailure sf)
+        {
+            sf.setDetail_code("1410");
+            serializeException(sf, response.getOutputStream());
+        }
+        catch(InvalidToken it)
+        {
+            it.setDetail_code("1430");
+            serializeException(it, response.getOutputStream());
+        }
+    }
+    
+	/**
+     * handle the replicate action for MN
+	 * @throws Exception 
+     */
+    private void replicate() throws Exception {
+
+        System.out.println("in POST replicate()");
+
+        File tmpDir = getTempDirectory();
+        System.out.println("temp dir: " + tmpDir.getAbsolutePath());
+        MultipartRequestResolver mrr = new MultipartRequestResolver(
+                tmpDir.getAbsolutePath(), 1000000000, 0);
+        MultipartRequest mr = mrr.resolveMultipart(request);
+        Map<String, File> files = mr.getMultipartFiles();
+        Iterator keys = files.keySet().iterator();
+        while(keys.hasNext()) {
+            String key = (String)keys.next();
+            System.out.println("files key: " + key);
+            System.out.println("files value: " + files.get(key));
+        }
+        
+        Map<String, List<String>> params = mr.getMultipartParameters();
+        keys = params.keySet().iterator();
+        while(keys.hasNext()) {
+            String key = (String)keys.next();
+            System.out.println("params key: " + key);
+            System.out.println("params value: " + params.get(key));
+        }
+        
+        // File f = files.get("sysmeta");
+        // the files are not being keyed by the part name, but rather the filename
+        File f = files.get(files.keySet().iterator().next());
+        
+        System.out.println("file: " + f.getAbsolutePath());
+        FileInputStream fis = new FileInputStream(f);
+
+        String sn = params.get("sourceNode").get(0);
+        System.out.println("sourceNode: " + sn);
+        NodeReference sourceNode = (NodeReference) deserializeServiceType(NodeReference.class, new ByteArrayInputStream(sn.getBytes("UTF-8")));
+        
+        //parse the systemMetadata
+        SystemMetadata sysmeta = (SystemMetadata) deserializeServiceType(SystemMetadata.class, fis);
+
+        MNodeService.getInstance().replicate(session, sysmeta, sourceNode);
+
+        response.setStatus(200);
+
+    }
+    
+    /**
+     * Get the Node information
+     * 
+     * @throws JiBXException
+     * @throws IOException
+     * @throws InvalidRequest 
+     * @throws ServiceFailure 
+     * @throws NotAuthorized 
+     * @throws NotImplemented 
+     */
+    private void node() 
+        throws JiBXException, IOException, NotImplemented, NotAuthorized, ServiceFailure, InvalidRequest {
+        
+        Node n = MNodeService.getInstance().getCapabilities();
+        
+        NodeList nl = new NodeList();
+        nl.addNode(n);
+        
+        response.setContentType("text/xml");
+        response.setStatus(200);
+        serializeServiceType(NodeList.class, nl, response.getOutputStream());
+        
+    }
+    
+    /**
+     * MN_crud.describe()
+     * http://mule1.dataone.org/ArchitectureDocs/mn_api_crud.html#MN_crud.describe
+     * @param guid
+     */
+    private void describeObject(String guid)
+    {
+        Logger logMetacat = Logger.getLogger(MNResourceHandler.class);
+        OutputStream out = null;
+        try
+        {
+            out = response.getOutputStream();
+        }
+        catch(Exception e)
+        {
+            logMetacat.error("Error getting output stream in ResourceHandler.describeObject: " + e.getClass() + ": " + e.getMessage());
+            return;
+        }
+        response.setStatus(200);
+        response.setContentType("text/xml");
+        Identifier id = new Identifier();
+        id.setValue(guid);
+        try
+        {
+            DescribeResponse dr = MNodeService.getInstance().describe(session, id);
+            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SZ");
+            response.addHeader("guid", guid);
+            response.addHeader("checksum", dr.getDataONE_Checksum().getValue());
+            response.addHeader("checksum_algorithm", dr.getDataONE_Checksum().getAlgorithm().name());
+            response.addHeader("content_length", dr.getContent_Length() + "");
+            response.addHeader("last_modified", dateFormat.format(dr.getLast_Modified()));
+            response.addHeader("format", dr.getDataONE_ObjectFormat().toString());
+        }
+        catch(InvalidRequest ir)
+        {
+            serializeException(ir, out);
+        }
+        catch(NotImplemented ni)
+        {
+            serializeException(ni, out);
+        }
+        catch(NotAuthorized na)
+        {
+            serializeException(na, out);
+        }
+        catch(ServiceFailure sf)
+        {
+            serializeException(sf, out);
+        }
+        catch(NotFound nf)
+        {
+            serializeException(nf, out);
+        }
+        catch(InvalidToken it)
+        {
+            serializeException(it, out);
+        }
+    }
+    
+    /**
+     * get the logs based on passed params.  Available 
+     * See http://mule1.dataone.org/ArchitectureDocs/mn_api_crud.html#MN_crud.getLogRecords
+     * for more info
+     */
+    private void getLog()
+    {
+        OutputStream out = null;
+        try {
+            
+            Date fromDate = null;
+            Date toDate = null;
+            Event event = null;
+            Integer start = null;
+            Integer count = null;
+            
+            try {
+            	String fromDateS = params.get("fromDate")[0];
+                System.out.println("param fromDateS: " + fromDateS);
+                fromDate = parseDateAndConvertToGMT(fromDateS);
+            } catch (Exception e) {
+            	logMetacat.warn("Could not parse fromDate: " + e.getMessage());
+            }
+            try {
+            	String toDateS = params.get("toDate")[0];
+                System.out.println("param toDateS: " + toDateS);
+                toDate = parseDateAndConvertToGMT(toDateS);
+            } catch (Exception e) {
+            	logMetacat.warn("Could not parse toDate: " + e.getMessage());
+			}
+            try {
+            	String eventS = params.get("event")[0];
+                event = Event.convert(eventS);
+            } catch (Exception e) {
+            	logMetacat.warn("Could not parse event: " + e.getMessage());
+			}
+            System.out.println("fromDate: " + fromDate + " toDate: " + toDate);
+            
+            try {
+            	start =  Integer.parseInt(params.get("start")[0]);
+            } catch (Exception e) {
+				logMetacat.warn("Could not parse start: " + e.getMessage());
+			}
+            try {
+            	count =  Integer.parseInt(params.get("count")[0]);
+            } catch (Exception e) {
+				logMetacat.warn("Could not parse count: " + e.getMessage());
+			}
+            
+            System.out.println("calling getLogRecords");
+            Log log = MNodeService.getInstance().getLogRecords(session, fromDate, toDate, event, start, count);
+            
+            out = response.getOutputStream();
+            response.setStatus(200);
+            response.setContentType("text/xml");
+            
+            serializeServiceType(Log.class, log, out);
+        }
+        catch(Exception e) {
+            String msg = "Could not get logs: " + e.getClass() + ": " + e.getMessage();
+            response.setStatus(500);
+            ServiceFailure sf = new ServiceFailure("1490", msg);
+            logMetacat.error(msg);
+            e.printStackTrace();
+            serializeException(sf, out);
+        }
+    }
+    
+    /**
+     * Implements REST version of DataONE CRUD API --> get
+     * @param guid ID of data object to be read
+     */
+    @Override
+    protected void getObject(String guid) {
+        OutputStream out = null;
+        try {
+            out = response.getOutputStream();
+            response.setStatus(200);
+            
+            if(guid != null)
+            { //get a specific document                
+                Identifier id = new Identifier();
+                id.setValue(guid);
+                try
+                {
+                    
+                    SystemMetadata sm = MNodeService.getInstance().getSystemMetadata(session, id);
+                    
+                    //set the content type
+                    if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
+                    		ObjectFormatCache.getInstance().getFormat("text/csv").getFmtid().getValue()))
+                    {
+                        response.setContentType("text/csv");
+                        response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".csv");
+                    }
+                    else if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
+                    		ObjectFormatCache.getInstance().getFormat("text/plain").getFmtid().getValue()))
+                    {
+                        response.setContentType("text/plain");
+                        response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".txt");
+                    } 
+                    else if(sm.getObjectFormat().getFmtid().getValue().trim().equals(
+                    		ObjectFormatCache.getInstance().getFormat("application/octet-stream").getFmtid().getValue()))
+                    {
+                        response.setContentType("application/octet-stream");
+                    }
+                    else
+                    {
+                        response.setContentType("text/xml");
+                        response.setHeader("Content-Disposition", "inline; filename=" + id.getValue() + ".xml");
+                    }
+                    
+                    InputStream data = MNodeService.getInstance().get(session, id);
+                    IOUtils.copyLarge(data, response.getOutputStream());
+                }
+                catch(InvalidToken it)
+                {
+                    response.setStatus(500);
+                    serializeException(it, out); 
+                }
+                catch(ServiceFailure sf)
+                {
+                    response.setStatus(500);
+                    serializeException(sf, out); 
+                }
+                catch(NotAuthorized na)
+                {
+                    response.setStatus(500);
+                    serializeException(na, out); 
+                }
+                catch(NotFound nf)
+                {
+                    response.setStatus(500);
+                    serializeException(nf, out); 
+                }
+                catch(NotImplemented ni)
+                {
+                    response.setStatus(500);
+                    serializeException(ni, out); 
+                }
+                catch(Exception e)
+                {
+                    response.setStatus(500);
+                    System.out.println("Error with Crud.get().  " +
+                            "If this is an 'Exception producing data' error, " +
+                            "go to CrudService.get() for better debugging.  " +
+                            "Here's the error: " + e.getClass() + ": " + e.getMessage());
+                    e.printStackTrace();
+                    ServiceFailure sf = new ServiceFailure("1030", 
+                            "IO Error in ResourceHandler.getObject: " + e.getClass() + ": " + e.getMessage());
+                    serializeException(sf, out); 
+                }
+            }
+            else
+            { //call listObjects with specified params
+                Date startTime = null;
+                Date endTime = null;
+                ObjectFormat objectFormat = null;
+                boolean replicaStatus = false;
+                int start = 0;
+                //TODO: make the max count into a const
+                int count = 1000;
+                Enumeration paramlist = request.getParameterNames();
+                while (paramlist.hasMoreElements()) 
+                { //parse the params and make the crud call
+                    String name = (String) paramlist.nextElement();
+                    String[] value = (String[])request.getParameterValues(name);
+                    /*for(int i=0; i<value.length; i++)
+                    {
+                        System.out.println("name: " + name + " value: " + value[i]);
+                    }*/
+                    if(name.equals("startTime") && value != null)
+                    {
+                        try
+                        {
+                          //startTime = dateFormat.parse(value[0]);
+                            startTime = parseDateAndConvertToGMT(value[0]);
+                        }
+                        catch(Exception e)
+                        {  //if we can't parse it, just don't use the startTime param
+                            System.out.println("Could not parse startTime: " + value[0]);
+                            startTime = null;
+                        }
+                    }
+                    else if(name.equals("endTime") && value != null)
+                    {
+                        try
+                        {
+                          //endTime = dateFormat.parse(value[0]);
+                            endTime = parseDateAndConvertToGMT(value[0]);
+                        }
+                        catch(Exception e)
+                        {  //if we can't parse it, just don't use the endTime param
+                            System.out.println("Could not parse endTime: " + value[0]);
+                            endTime = null;
+                        }
+                    }
+                    else if(name.equals("objectFormat") && value != null) 
+                    {
+                        objectFormat = ObjectFormatCache.getInstance().getFormat(value[0]);
+                    }
+                    else if(name.equals("replicaStatus") && value != null)
+                    {
+                        if(value != null && 
+                           value.length > 0 && 
+                           (value[0].equals("true") || value[0].equals("TRUE") || value[0].equals("YES")))
+                        {
+                            replicaStatus = true;
+                        }
+                    }
+                    else if(name.equals("start") && value != null)
+                    {
+                        start = new Integer(value[0]).intValue();
+                    }
+                    else if(name.equals("count") && value != null)
+                    {
+                        count = new Integer(value[0]).intValue();
+                    }
+                }
+                //make the crud call
+                System.out.println("session: " + session + " startTime: " + startTime +
+                        " endtime: " + endTime + " objectFormat: " + 
+                        objectFormat + " replicaStatus: " + replicaStatus + 
+                        " start: " + start + " count: " + count);
+               
+                ObjectList ol = MNodeService.getInstance().listObjects(session, startTime, endTime, 
+                        objectFormat, replicaStatus, start, count);
+                
+                StringReader sr = new StringReader(ol.toString());                
+                out = response.getOutputStream();  
+                response.setStatus(200);
+                response.setContentType("text/xml");
+                // Serialize and write it to the output stream
+                
+                try {
+                    serializeServiceType(ObjectList.class, ol, out);
+                } catch (JiBXException e) {
+                    throw new ServiceFailure("1190", "Failed to serialize ObjectList: " + e.getMessage());
+                }
+            }
+        } catch (BaseException e) {
+                response.setStatus(500);
+                serializeException(e, out);
+        } catch (IOException e) {
+            e.printStackTrace();
+            response.setStatus(500);
+            ServiceFailure sf = new ServiceFailure("1030", 
+                    "IO Error in ResourceHandler.getObject: " + e.getMessage());
+            serializeException(sf, out); 
+        } catch(NumberFormatException ne) {
+            response.setStatus(500);
+            InvalidRequest ir = new InvalidRequest("1030", "Invalid format for parameter: " + ne.getMessage());
+            serializeException(ir, out);
+        } catch (Exception e) {
+            e.printStackTrace();
+            response.setStatus(500);
+            ServiceFailure sf = new ServiceFailure("1030", 
+                    "Exception " + e.getClass().getName() + " raised while handling listObjects request: " + 
+                    e.getMessage());
+            serializeException(sf, out);
+        }
+    }
+    
+    /**
+     * Implements REST version of DataONE CRUD API --> getSystemMetadata
+     * @param guid ID of data object to be read
+     */
+    @Override
+    protected void getSystemMetadataObject(String guid) {
+        OutputStream out = null;
+        try {
+            response.setContentType("text/xml");
+            response.setStatus(200);
+            out = response.getOutputStream();
+            Identifier id = new Identifier();
+            id.setValue(guid);
+            SystemMetadata sysmeta = MNodeService.getInstance().getSystemMetadata(session, id);
+            
+            // Serialize and write it to the output stream
+            try {
+                serializeServiceType(SystemMetadata.class, sysmeta, out);
+            } catch (JiBXException e) {
+                throw new ServiceFailure("1190", "Failed to serialize SystemMetadata: " + e.getMessage());
+            }
+        } catch (BaseException e) {
+            response.setStatus(500);
+                serializeException(e, out);
+        } catch (IOException e) {
+            response.setStatus(500);
+            ServiceFailure sf = new ServiceFailure("1030", 
+                    "IO Error in ResourceHandler.getSystemMetadataObject: " + e.getMessage());
+            serializeException(sf, out);
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+    }
+    
+    /**
+     * Earthgrid API > Query Service > Query Function : translates ecogrid query document to metacat query 
+     * then calls DBQuery > createResultDocument function and then again translate resultset to ecogrid resultset
+     * 
+     * NOTE:
+     *      This is the only method that uses EcoGrid classes for its implementation.  
+     *      It does so because it takes an EcoGrid Query as input, and outputs an
+     *      EcoGrid ResultSet document.  These documents are parsed by the auto-generated
+     *      EcoGrid classes from axis, and so we link to them here rather than re-inventing them.
+     *      This creates a circular dependency, because the Metacat classes are needed
+     *      to build the EcoGrid implementation, and the EcoGrid jars are needed to build this query()
+     *      method.  This circularity could be resolved by moving the EcoGrid classes
+     *      to Metacat directly.  As we transition away from EcoGrid SOAP methods in
+     *      favor of these REST interfaces, this circular dependency can be eliminated.
+     *        
+     * @throws Exception
+     */
+    private void query() throws Exception {
+        /*  This block commented out because of the EcoGrid circular dependency.
+         *  For now, query will not be supported until the circularity can be
+         *  resolved, probably by moving the ecogrid query syntax transformers
+         *  directly into the Metacat codebase.  MBJ 2010-02-03
+         
+        try {
+            EcogridQueryParser parser = new EcogridQueryParser(request
+                    .getReader());
+            parser.parseXML();
+            QueryType queryType = parser.getEcogridQuery();
+            EcogridJavaToMetacatJavaQueryTransformer queryTransformer = 
+                new EcogridJavaToMetacatJavaQueryTransformer();
+            QuerySpecification metacatQuery = queryTransformer
+                    .transform(queryType);
+
+            DBQuery metacat = new DBQuery();
+
+            boolean useXMLIndex = (new Boolean(PropertyService
+                    .getProperty("database.usexmlindex"))).booleanValue();
+            String xmlquery = "query"; // we don't care the query in resultset,
+            // the query can be anything
+            PrintWriter out = null; // we don't want metacat result, so set out null
+
+            // parameter: queryspecification, user, group, usingIndexOrNot
+            StringBuffer result = metacat.createResultDocument(xmlquery,
+                    metacatQuery, out, username, groupNames, useXMLIndex);
+
+            // create result set transfer       
+            String saxparser = PropertyService.getProperty("xml.saxparser");
+            MetacatResultsetParser metacatResultsetParser = new MetacatResultsetParser(
+                    new StringReader(result.toString()), saxparser, queryType
+                            .getNamespace().get_value());
+            ResultsetType records = metacatResultsetParser.getEcogridResult();
+
+            System.out
+                    .println(EcogridResultsetTransformer.toXMLString(records));
+            response.setContentType("text/xml");
+            out = response.getWriter();
+            out.print(EcogridResultsetTransformer.toXMLString(records));
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }*/
+        response.setContentType("text/xml");
+        response.setStatus(501);
+        PrintWriter out = response.getWriter();
+        out.print("<error>Query operation not yet supported by Metacat.</error>");
+        out.close();
+    }
+    
+    /**
+     * return a tmp file with a given name
+     * @param name
+     * @return
+     */
+    private static File getTempFile(String name)
+    {
+        File tmpDir = getTempDirectory();
+        File f = new File(tmpDir, name);
+        return f;
+    }
+    
+    /**
+     * return a temp file with a default name
+     * @return
+     */
+    private static File getTempFile()
+    {
+        return getTempFile(new Date().getTime() + ".tmp");
+    }
+    
+    /**
+     * Inserts or updates the object
+     * 
+     * @param guid - ID of data object to be inserted or updated.  If action is update, the pid
+     *               is the existing pid.  If insert, the pid is the new one
+     */
+    @Override
+    protected void putObject(String pid, String action) {
+        System.out.println("ResourceHandler: putObject with pid " + pid);
+        logMetacat.debug("Entering putObject: " + pid + "/" + action);
+        OutputStream out = null;
+        try {
+            out = response.getOutputStream();
+            response.setStatus(200);
+            response.setContentType("text/xml");
+        } catch (IOException e1) {
+            logMetacat.error("Could not get the output stream for writing in putObject");
+        }
+        try {
+            
+            // Read the incoming data from its Mime Multipart encoding
+            logMetacat.debug("Disassembling MIME multipart form");
+            InputStream object = null;
+            InputStream sysmeta = null;
+            Map<String, List<String>> multipartparams;
+            
+            try {
+
+                // handle MMP inputs
+                File tmpDir = getTempDirectory();
+                System.out.println("temp dir: " + tmpDir.getAbsolutePath());
+                MultipartRequestResolver mrr = 
+                	new MultipartRequestResolver(tmpDir.getAbsolutePath(), 1000000000, 0);
+                MultipartRequest mr = mrr.resolveMultipart(request);
+                System.out.println("resolved multipart request");
+                Map<String, File> files = mr.getMultipartFiles();
+                if (files == null) {
+                    throw new ServiceFailure("1202", "create/update must have multipart files with names 'object' and 'sysmeta'");
+                }
+                System.out.println("got multipart files");
+                
+                if (files.keySet() == null) {
+                    System.out.println("No file keys in MMP request.");
+                    throw new ServiceFailure("1202", "No file keys found in MMP.  " +
+                            "create/update must have multipart files with names 'object' and 'sysmeta'");
+                }
+
+				// for logging purposes, dump out the key-value pairs that constitute the request
+				// 3 types exist: request params, multipart params, and multipart files
+                Iterator it = files.keySet().iterator();
+                System.out.println("iterating through files");
+                while (it.hasNext()) {
+                    String key = (String)it.next();
+                    System.out.println("files key: " + key);
+                    System.out.println("files value: " + files.get(key));
+                }
+                
+                multipartparams = mr.getMultipartParameters();
+                it = multipartparams.keySet().iterator();
+                System.out.println("iterating through multipartparams");
+                while (it.hasNext()) {
+                    String key = (String)it.next();
+                    System.out.println("multipartparams key: " + key);
+                    System.out.println("multipartparams value: " + multipartparams.get(key));
+                }
+                
+                it = params.keySet().iterator();
+                System.out.println("iterating through params");
+                while (it.hasNext()) {
+                    String key = (String)it.next();
+                    System.out.println("param key: " + key);
+                    System.out.println("param value: " + params.get(key));
+                }
+                System.out.println("done iterating the request...");
+
+                File smFile = files.get("sysmeta");
+				if (smFile == null) {
+				    throw new InvalidRequest("1102", "Missing the required file-part 'sysmeta' from the multipart request.");
+				}
+                System.out.println("smFile: " + smFile.getAbsolutePath());
+                sysmeta = new FileInputStream(smFile);
+                File objFile = files.get("object");
+				if (objFile == null) {
+				    throw new InvalidRequest("1102", "Missing the required file-part 'object' from the multipart request.");
+				}
+                System.out.println("objectfile: " + objFile.getAbsolutePath());
+                object = new FileInputStream(objFile);
+                
+            }
+            catch (FileUploadException fue)
+            {
+                throw new ServiceFailure("1202", "Could not upload MMP files: " + fue.getMessage());
+            }
+            catch (IOException ioe)
+            {
+                throw new ServiceFailure("1202", 
+                        "IOException when processing Mime Multipart: " + ioe.getMessage());
+            }
+            catch (Exception e)
+            {
+                throw new ServiceFailure("1202", "Error handling MMP upload: " + e.getClass() + ": " + e.getMessage());
+            }
+            
+            // handle inserts
+            if (action.equals(FUNCTION_NAME_INSERT)) { 
+
+                logMetacat.debug("Commence creation...");
+                SystemMetadata smd = (SystemMetadata) deserializeServiceType(SystemMetadata.class, sysmeta);
+
+                Identifier id = new Identifier();
+                id.setValue(pid);
+                System.out.println("creating object with pid " + pid);
+                Identifier rId = MNodeService.getInstance().create(session, id, object, smd);
+                serializeServiceType(Identifier.class, rId, out);
+                
+            } else if (action.equals(FUNCTION_NAME_UPDATE)) { 
+
+                // check that the newPid parameter was provided
+                if (multipartparams.get("newPid") == null) {
+                    throw new InvalidRequest("1202", "'newPid' must be contained in the request parameters.");
+                }
+                String newPidString = multipartparams.get("newPid").get(0);
+                
+                Identifier newPid = new Identifier();
+                Identifier obsoletedPid = new Identifier();
+                newPid.setValue(newPidString);
+                obsoletedPid.setValue(pid);
+               
+                logMetacat.debug("Commence update...");
+                
+                //get the systemmetadata object
+                SystemMetadata smd = (SystemMetadata) deserializeServiceType(SystemMetadata.class, sysmeta);
+
+                Identifier rId = MNodeService.getInstance().update(session, newPid, object, obsoletedPid, smd);
+                serializeServiceType(Identifier.class, rId, out);
+            } else {
+                throw new InvalidRequest("1000", "Operation must be create or update.");
+            }
+            
+            //clean up the MMP files
+            //parts.get("systemmetadata").delete();
+            //parts.get("object").delete();
+        } catch (NotAuthorized e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InvalidToken e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (ServiceFailure e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (NotFound e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (IdentifierNotUnique e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (UnsupportedType e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InsufficientResources e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InvalidSystemMetadata e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (NotImplemented e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InvalidRequest e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (JiBXException e) {
+            response.setStatus(500);
+            e.printStackTrace(System.out);
+            InvalidSystemMetadata ism = new InvalidSystemMetadata("1080", e.getMessage());
+            serializeException(ism, out);
+        }
+    }
+
+    /**
+     * Handle delete 
+     * @param guid ID of data object to be deleted
+     * @throws IOException
+     */
+    private void deleteObject(String guid) throws IOException 
+    {
+
+        OutputStream out = response.getOutputStream();
+        response.setStatus(200);
+        response.setContentType("text/xml");
+
+        Identifier id = new Identifier();
+        id.setValue(guid);
+        try {
+            System.out.println("Calling delete");
+            MNodeService.getInstance().delete(session, id);
+            serializeServiceType(Identifier.class, id, out);
+        } 
+        catch (NotAuthorized e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InvalidToken e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (ServiceFailure e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (NotImplemented e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch (InvalidRequest e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch(NotFound e) {
+            response.setStatus(500);
+            serializeException(e, out);
+        } catch(JiBXException e) {
+            response.setStatus(500);
+            serializeException(new ServiceFailure("1350", "JiBXException: " + e.getMessage()), out);
+        }
+        out.close();
+    }
+    
+    /**
+     * set the access perms on a document
+     * @throws Exception
+     */
+    @Override
+    protected void setaccess() throws Exception
+    {
+        try
+        {
+            String guid = params.get("guid")[0];
+            Identifier id = new Identifier();
+            id.setValue(guid);
+            String accesspolicy = params.get("accesspolicy")[0];
+            AccessPolicy accessPolicy = (AccessPolicy) deserializeServiceType(AccessPolicy.class, new ByteArrayInputStream(accesspolicy.getBytes("UTF-8")));
+            MNodeService.getInstance().setAccessPolicy(session, id, accessPolicy);
+        }
+        catch(Exception e)
+        {
+            response.setStatus(500);
+            printError("Error setting access in ResourceHandler: " + e.getClass() + ": " + e.getMessage(), response);
+            throw e;
+        }
+    }
+
+}

Property changes on: src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: src/edu/ucsb/nceas/metacat/restservice/MNRestServlet.java
===================================================================
--- src/edu/ucsb/nceas/metacat/restservice/MNRestServlet.java	(nonexistent)
+++ src/edu/ucsb/nceas/metacat/restservice/MNRestServlet.java	(revision 6264)
@@ -0,0 +1,47 @@
+/**
+ *  '$RCSfile$'
+ *  Copyright: 2000 Regents of the University of California and the
+ *              National Center for Ecological Analysis and Synthesis
+ *
+ *   '$Author$'
+ *     '$Date$'
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+package edu.ucsb.nceas.metacat.restservice;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * Routes MN REST service requests to the appropriate handler
+ *  
+ */
+public class MNRestServlet extends RestServlet {
+    
+	/**
+	 * Provide an MNResourceHandler subclass of ResourceHandler
+	 */
+	@Override
+    protected ResourceHandler createHandler(HttpServletRequest request, HttpServletResponse response) 
+    	throws ServletException, IOException {
+        return new MNResourceHandler(getServletContext(), request, response);
+    }
+
+}

Property changes on: src/edu/ucsb/nceas/metacat/restservice/MNRestServlet.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
