You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2007/10/11 15:00:15 UTC

svn commit: r583812 [2/2] - in /roller/branches/roller_4.1_dev/apps/weblogger/src/java/org/apache/roller/weblogger/webservices/atomprotocol: CommentCollection.java EntryCollection.java MediaCollection.java RollerAtomHandler.java

Modified: roller/branches/roller_4.1_dev/apps/weblogger/src/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java
URL: http://svn.apache.org/viewvc/roller/branches/roller_4.1_dev/apps/weblogger/src/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java?rev=583812&r1=583811&r2=583812&view=diff
==============================================================================
--- roller/branches/roller_4.1_dev/apps/weblogger/src/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java (original)
+++ roller/branches/roller_4.1_dev/apps/weblogger/src/java/org/apache/roller/weblogger/webservices/atomprotocol/RollerAtomHandler.java Thu Oct 11 06:00:14 2007
@@ -16,67 +16,32 @@
 * directory of this distribution.
 */
 package org.apache.roller.weblogger.webservices.atomprotocol;
+import com.sun.syndication.propono.atom.common.Categories;
 import com.sun.syndication.propono.atom.server.AtomRequest;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
 import java.util.StringTokenizer;
-import java.util.Collections;
-import javax.activation.MimetypesFileTypeMap;
 import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.roller.weblogger.business.FileManager;
 import org.apache.roller.weblogger.business.Weblogger;
 import org.apache.roller.weblogger.business.WebloggerFactory;
 import org.apache.roller.weblogger.pojos.User;
-import org.apache.roller.weblogger.pojos.WeblogCategory;
 import org.apache.roller.weblogger.pojos.WeblogEntry;
 import org.apache.roller.weblogger.pojos.Weblog;
 import org.apache.roller.weblogger.util.Utilities;
 import org.apache.roller.weblogger.util.WSSEUtilities;
-import com.sun.syndication.feed.atom.Content;
-import com.sun.syndication.feed.atom.Category;
 import com.sun.syndication.feed.atom.Entry;
 import com.sun.syndication.feed.atom.Feed;
-import com.sun.syndication.feed.atom.Link;
-import com.sun.syndication.feed.atom.Person;
 import com.sun.syndication.propono.atom.common.AtomService;
-import com.sun.syndication.propono.atom.common.Categories;
-import com.sun.syndication.propono.atom.common.rome.AppModule;
-import com.sun.syndication.propono.atom.common.rome.AppModuleImpl;
 import com.sun.syndication.propono.atom.server.AtomException;
 import com.sun.syndication.propono.atom.server.AtomHandler;
 import com.sun.syndication.propono.atom.server.AtomMediaResource;
 import com.sun.syndication.propono.atom.server.AtomNotAuthorizedException;
 import com.sun.syndication.propono.atom.server.AtomNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.SimpleDateFormat;
-import java.util.Comparator;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.UUID;
-import javax.activation.FileTypeMap;
 import org.apache.commons.lang.StringUtils;
 import org.apache.roller.weblogger.WebloggerException;
-import org.apache.roller.weblogger.business.FileIOException;
-import org.apache.roller.weblogger.business.URLStrategy;
 import org.apache.roller.weblogger.config.WebloggerConfig;
-import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
-import org.apache.roller.weblogger.business.WeblogEntryManager;
-import org.apache.roller.weblogger.business.WeblogManager;
-import org.apache.roller.weblogger.business.search.IndexManager;
-import org.apache.roller.weblogger.pojos.WeblogEntryTag;
-import org.apache.roller.weblogger.pojos.ThemeResource;
 import org.apache.roller.weblogger.pojos.WeblogPermission;
-import org.apache.roller.weblogger.util.cache.CacheManager;
 
 /**
  * Weblogger's ROME Propono-based Atom Protocol implementation.
@@ -89,9 +54,11 @@
  * Here are the APP URIs suppored by Weblogger:
  * 
  * <pre>
+ * 
  *    /roller-services/app
  *    Introspection doc
  * 
+ * 
  *    /roller-services/app/[weblog-handle>/entries
  *    Entry collection for a blog
  * 
@@ -100,6 +67,7 @@
  * 
  *    /roller-services/app/[weblog-handle]/entry/[id]
  *    Individual entry (i.e. edit URI)
+ *
  * 
  *    /roller-services/app/[weblog-handle]/resources
  *    Resource (i.e. file-uploads) collection for a blog
@@ -113,6 +81,17 @@
  *    /roller-services/app/[weblog-handle]/resource/[name]
  *    Individual resource data (i.e. media-edit URI)
  * 
+ *  Coming soon...
+ *
+ *    /roller-services/app/[weblog-handle]/entry/[id]/comments
+ *    Comments collection for entry with id
+ * 
+ *    /roller-services/app/[weblog-handle]/entry/[id]/comments/[offset]
+ *    Comments collection for entry with id
+ * 
+ *    /roller-services/app/[weblog-handle]/entry/[id]/comments/id
+ *    Individual comment
+ * 
  * </pre>
  * @author David M Johnson
  */
@@ -133,7 +112,7 @@
             .getBooleanProperty("webservices.atomprotocol.oneSecondThrottle");
     }
     
-    //---------------------------------------------------------------- construction
+    //------------------------------------------------------------ construction
     
     /**
      * Create Atom handler for a request and attempt to authenticate user.
@@ -168,7 +147,7 @@
         return ret;
     }
     
-    //---------------------------------------------------------------- introspection
+    //----------------------------------------------------------- introspection
     
     /**
      * Return Atom service document for site, getting blog-name from pathInfo.
@@ -183,7 +162,31 @@
         }
     }
      
-    //----------------------------------------------------------------- collections
+    //----------------------------------------------------------------- create
+
+    /**
+     * Create entry in the entry collection (a Weblogger blog has only one).
+     */
+    public String postEntry(AtomRequest areq, Entry entry) throws AtomException {
+        EntryCollection ecol = new EntryCollection(user, atomURL);
+        return ecol.postEntry(areq, entry);
+    }
+    
+    
+    /**
+     * Create new resource in generic collection (a Weblogger blog has only one).
+     * TODO: can we avoid saving temporary file?
+     * TODO: do we need to handle mutli-part MIME uploads?
+     * TODO: use Jakarta Commons File-upload?
+     */
+    public String postMedia(AtomRequest areq, Entry entry)
+            throws AtomException {
+        MediaCollection mcol = new MediaCollection(user, atomURL);
+        return mcol.postMedia(areq, entry);
+    }
+    
+
+    //----------------------------------------------------------------- retrieve 
     
     /**
      * Return collection specified by pathinfo.
@@ -197,647 +200,98 @@
      */
     public Feed getCollection(AtomRequest areq) throws AtomException {
         String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
+        
         if (pathInfo.length > 0 && pathInfo[1].equals("entries")) {
-            return getCollectionOfEntries(areq);
+            EntryCollection ecol = new EntryCollection(user, atomURL);
+            return ecol.getCollection(areq);
+            
         } else if (pathInfo.length > 0 && pathInfo[1].equals("resources")) {
-            return getCollectionOfResources(areq);
+            MediaCollection mcol = new MediaCollection(user, atomURL);
+            return mcol.getCollection(areq);
         }
         throw new AtomNotFoundException("Cannot find collection specified");
     }
     
-    /**
-     * Helper method that returns collection of entries, called by getCollection().
-     */
-    public Feed getCollectionOfEntries(AtomRequest areq) throws AtomException {
-        log.debug("Entering");
-        String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            int start = 0;
-            int max = maxEntries;
-            if (pathInfo.length > 2) {
-                try {
-                    String s = pathInfo[2].trim();
-                    start = Integer.parseInt(s);
-                } catch (Throwable t) {
-                    log.warn("Unparsable range: " + pathInfo[2]);
-                }
-            }        
-            String handle = pathInfo[0];
-            String absUrl = WebloggerRuntimeConfig.getAbsoluteContextURL();
-            Weblog website = roller.getWeblogManager().getWeblogByHandle(handle);
-            if (website == null) {
-                throw new AtomNotFoundException("Cannot find specified weblog");
-            }
-            if (!canView(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to access website: " + handle);
-            }
-            List entries = entries = roller.getWeblogEntryManager().getWeblogEntries( 
-                    website,           // website
-                    null,              // user
-                    null,              // startDate
-                    null,              // endDate
-                    null,              // catName
-                    null,              // tags
-                    null,              // status
-                    null,              // text
-                    "updateTime",      // sortby
-                    null,
-                    null,              // locale
-                    start,             // offset (for range paging)
-                    max + 1);          // maxEntries
-            Feed feed = new Feed();
-            feed.setId(atomURL
-                +"/"+website.getHandle() + "/entries/" + start);
-            feed.setTitle(website.getName());
-
-            Link link = new Link();
-            link.setHref(absUrl + "/" + website.getHandle());
-            link.setRel("alternate");
-            link.setType("text/html");
-            feed.setAlternateLinks(Collections.singletonList(link));
-
-            List atomEntries = new ArrayList();
-            int count = 0;
-            for (Iterator iter = entries.iterator(); iter.hasNext() && count < maxEntries; count++) {
-                WeblogEntry rollerEntry = (WeblogEntry)iter.next();
-                Entry entry = createAtomEntry(rollerEntry);
-                atomEntries.add(entry);
-                if (count == 0) {
-                    // first entry is most recent
-                    feed.setUpdated(entry.getUpdated());
-                }
-            }
-            List links = new ArrayList();
-            if (entries.size() > max) { // add next link
-                int nextOffset = start + max;
-                String url = atomURL+"/"
-                        + website.getHandle() + "/entries/" + nextOffset;
-                Link nextLink = new Link();
-                nextLink.setRel("next");
-                nextLink.setHref(url);
-                links.add(nextLink);
-            }
-            if (start > 0) { // add previous link
-                int prevOffset = start > max ? start - max : 0;
-                String url = atomURL+"/"
-                        +website.getHandle() + "/entries/" + prevOffset;
-                Link prevLink = new Link();
-                prevLink.setRel("previous");
-                prevLink.setHref(url);
-                links.add(prevLink);
-            }
-            if (links.size() > 0) feed.setOtherLinks(links);
-            // Use collection URI as id
-            feed.setEntries(atomEntries);
-            
-            log.debug("Exiting");
-            return feed;
-        
-        } catch (WebloggerException re) {
-            throw new AtomException("Getting entry collection");
-        }
-    }
-    
-    /**
-     * Helper method that returns collection of resources, called by getCollection().
-     *   /handle/resources/offset
-     *   /handle/resources/path/offset
-     */
-    public Feed getCollectionOfResources(AtomRequest areq) throws AtomException {
-        log.debug("Entering");
-        String[] rawPathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            int start = 0;
-            int max = maxEntries;
-            String[] pathInfo = rawPathInfo;
-            if (rawPathInfo.length > 2) {
-                try {
-                    start = Integer.parseInt(rawPathInfo[rawPathInfo.length - 1]);
-                    pathInfo = new String[rawPathInfo.length - 1];
-                    for (int i=0; i<rawPathInfo.length - 1; i++) {
-                        pathInfo[i] = rawPathInfo[i];
-                    }
-                } catch (Exception ingored) {}
-            }
-            String path = filePathFromPathInfo(pathInfo);
-            if (!path.equals("")) path = path + File.separator;
-            
-            String handle = pathInfo[0];
-            String absUrl = WebloggerRuntimeConfig.getAbsoluteContextURL();
-            Weblog website = roller.getWeblogManager().getWeblogByHandle(handle);
-            if (website == null) {
-                throw new AtomNotFoundException("Cannot find weblog: " + handle);
-            }
-            if (!canView(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to access website");
-            }
-                        
-            Feed feed = new Feed();
-            feed.setId(atomURL
-                +"/"+website.getHandle() + "/resources/" + path + start);                
-            feed.setTitle(website.getName());
-
-            Link link = new Link();
-            link.setHref(absUrl + "/" + website.getHandle());
-            link.setRel("alternate");
-            link.setType("text/html");
-            feed.setAlternateLinks(Collections.singletonList(link));
-
-            FileManager fmgr = roller.getFileManager();
-            ThemeResource[] files = fmgr.getFiles(website, path);
-
-            SortedSet sortedSet = new TreeSet(new Comparator() {
-                public int compare(Object o1, Object o2) {
-                    ThemeResource f1 = (ThemeResource)o1;
-                    ThemeResource f2 = (ThemeResource)o2;
-                    if (f1.getLastModified() < f2.getLastModified()) return 1;
-                    else if (f1.getLastModified() == f2.getLastModified()) return 0;
-                    else return -1;
-                }
-            });
-                                    
-            if (files != null && start < files.length) {  
-                for (int j=0; j<files.length; j++) {
-                    sortedSet.add(files[j]);
-                }
-                int count = 0;
-                ThemeResource[] sortedResources = 
-                   (ThemeResource[])sortedSet.toArray(new ThemeResource[sortedSet.size()]);
-                List atomEntries = new ArrayList();
-                for (int i=start; i<(start + max) && i<(sortedResources.length); i++) {
-                    Entry entry = createAtomResourceEntry(website, sortedResources[i]);
-                    atomEntries.add(entry);
-                    if (count == 0) {
-                        // first entry is most recent
-                        feed.setUpdated(entry.getUpdated());
-                    }
-                    count++;
-                }
-
-                List otherLinks = new ArrayList();
-                if (start + count < files.length) { // add next link
-                    int nextOffset = start + max;
-                    String url = atomURL
-                        +"/"+ website.getHandle() + "/resources/" + path + nextOffset;
-                    Link nextLink = new Link();
-                    nextLink.setRel("next");
-                    nextLink.setHref(url);
-                    otherLinks.add(nextLink);
-                }
-                if (start > 0) { // add previous link
-                    int prevOffset = start > max ? start - max : 0;
-                    String url = atomURL
-                        +"/"+website.getHandle() + "/resources/" + path + prevOffset;
-                    Link prevLink = new Link();
-                    prevLink.setRel("previous");
-                    prevLink.setHref(url);
-                    otherLinks.add(prevLink);
-                }
-                feed.setOtherLinks(otherLinks);
-                feed.setEntries(atomEntries);
-            }
-            
-            log.debug("Existing");
-            return feed;
        
-        } catch (WebloggerException re) {
-            throw new AtomException("Getting resource collection");
-        }
+    public Categories getCategories(AtomRequest arg0) throws AtomException {
+        throw new UnsupportedOperationException("Not supported yet.");
     }
-    
-    //--------------------------------------------------------------------- entries
 
-    /**
-     * Create entry in the entry collection (a Weblogger blog has only one).
-     */
-    public String postEntry(AtomRequest areq, Entry entry) throws AtomException {
-        log.debug("Entering");
-        String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            // authenticated client posted a weblog entry
-            String handle = pathInfo[0];
-            Weblog website = 
-                roller.getWeblogManager().getWeblogByHandle(handle);
-            if (website == null) {
-                throw new AtomNotFoundException("Cannot find weblog: " + handle);
-            }
-            if (!canEdit(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to access website: " + handle);
-            }
-            
-            if (throttle) oneSecondThrottle();
-            
-            // Save it and commit it
-            WeblogEntryManager mgr = roller.getWeblogEntryManager();
-            WeblogEntry rollerEntry = new WeblogEntry();
-            rollerEntry.setWebsite(website);
-            rollerEntry.setCreatorUserName(this.user.getUserName());
-            copyToRollerEntry(entry, rollerEntry);
-            mgr.saveWeblogEntry(rollerEntry);
-            roller.flush();
 
-            CacheManager.invalidate(website);
-            if (rollerEntry.isPublished()) {
-                roller.getIndexManager().addEntryReIndexOperation(rollerEntry);
-            }
-            
-            Entry newEntry = createAtomEntry(rollerEntry);
-            for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) {
-                Link link = (Link)it.next();
-                if ("edit".equals(link.getRel())) {
-                    log.debug("Exiting");
-                    return link.getHrefResolved();
-                }
-            }
-            log.error("ERROR: no edit link found in saved media entry");
-            log.debug("Exiting");
-
-        } catch (WebloggerException re) {
-            throw new AtomException("Posting entry", re);
-        }
-        throw new AtomException("Posting entry");
-    }
-    
     /**
      * Retrieve entry, URI like this /blog-name/entry/id
      */
     public Entry getEntry(AtomRequest areq) throws AtomException {
         log.debug("Entering");
         String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            if (pathInfo.length > 2) // URI is /blogname/entries/entryid
-            {
-                if (pathInfo[1].equals("entry")) {
-                    WeblogEntry entry = 
-                        roller.getWeblogEntryManager().getWeblogEntry(pathInfo[2]);
-                    if (entry == null) {
-                        throw new AtomNotFoundException("Cannot find specified entry/resource");
-                    }
-                    if (!canView(entry)) {
-                        throw new AtomNotAuthorizedException("Not authorized to view entry");
-                    } else {
-                        return createAtomEntry(entry);
-                    }
-                } else if (pathInfo[1].equals("resource") && pathInfo[pathInfo.length - 1].endsWith(".media-link")) {
-                    String filePath = filePathFromPathInfo(pathInfo);
-                    filePath = filePath.substring(0, filePath.length() - ".media-link".length());
-                    String handle = pathInfo[0];
-                    Weblog website = 
-                        roller.getWeblogManager().getWeblogByHandle(handle);                    
-                    ThemeResource resource = 
-                        roller.getFileManager().getFile(website, filePath);
-                    
-                    log.debug("Exiting");
-                    if (resource != null) return createAtomResourceEntry(website, resource);
-                }
+        if (pathInfo.length > 2) // URI is /blogname/entries/entryid
+        {
+            if (pathInfo[1].equals("entry")) {
+                EntryCollection ecol = new EntryCollection(user, atomURL);
+                return ecol.getEntry(areq);
+
+            } else if (pathInfo[1].equals("resource") && pathInfo[pathInfo.length - 1].endsWith(".media-link")) {
+                MediaCollection mcol = new MediaCollection(user, atomURL);
+                return mcol.getEntry(areq);                    
             }
-            throw new AtomNotFoundException("Cannot find specified entry/resource");
-        } catch (WebloggerException re) {
-            throw new AtomException("Getting entry");
         }
+        throw new AtomNotFoundException("Cannot find specified entry/resource");
     }
     
     /**
      * Expects pathInfo of form /blog-name/resource/path/name
      */
     public AtomMediaResource getMediaResource(AtomRequest areq) throws AtomException {
-        log.debug("Entering");
-        String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            // authenticated client posted a weblog entry
-            File tempFile = null;
-            String handle = pathInfo[0];
-            FileManager fmgr = roller.getFileManager();
-            Weblog website = WebloggerFactory.getWeblogger().getWeblogManager().getWeblogByHandle(handle);
-            if (!canEdit(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to edit weblog: " + handle);
-            }
-            if (pathInfo.length > 1) {
-                try {                                        
-                    // Parse pathinfo to determine file path
-                    String filePath = filePathFromPathInfo(pathInfo);
-                    ThemeResource resource = fmgr.getFile(website, filePath);                    
-                    return new AtomMediaResource(
-                            resource.getName(), 
-                            resource.getLength(),
-                            new Date(resource.getLastModified()),
-                            resource.getInputStream());
-                } catch (Exception e) {
-                    throw new AtomException(
-                        "Unexpected error during file upload", e);
-                }
-            }
-            throw new AtomException("Incorrect path information");
-        
-        } catch (WebloggerException re) {
-            throw new AtomException("Posting media");
-        }
+        MediaCollection mcol = new MediaCollection(user, atomURL);
+        return mcol.getMediaResource(areq);
     }
     
+    
+    //----------------------------------------------------------------- update
+    
     /**
      * Update entry, URI like this /blog-name/entry/id
      */
     public void putEntry(AtomRequest areq, Entry entry) throws AtomException {
-        log.debug("Entering");
-        String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            if (pathInfo.length == 3) // URI is /blogname/entries/entryid
-            {
-                WeblogEntry rollerEntry =
-                    roller.getWeblogEntryManager().getWeblogEntry(pathInfo[2]);
-                if (rollerEntry == null) {
-                    throw new AtomNotFoundException(
-                        "Cannot find specified entry/resource");  
-                }
-                if (canEdit(rollerEntry)) {
-            
-                    if (throttle) oneSecondThrottle();
-                    
-                    WeblogEntryManager mgr = roller.getWeblogEntryManager();
-                    copyToRollerEntry(entry, rollerEntry);
-                    rollerEntry.setUpdateTime(new Timestamp(new Date().getTime()));
-                    mgr.saveWeblogEntry(rollerEntry);
-                    roller.flush();
-                    
-                    CacheManager.invalidate(rollerEntry.getWebsite());
-                    if (rollerEntry.isPublished()) {
-                        roller.getIndexManager().addEntryReIndexOperation(rollerEntry);
-                    }
-                    log.debug("Exiting");
-                    return;
-                }
-                throw new AtomNotAuthorizedException("ERROR not authorized to update entry");
-            }
-            throw new AtomNotFoundException("Cannot find specified entry/resource");
-            
-        } catch (WebloggerException re) {
-            throw new AtomException("Updating entry");
-        }
+        EntryCollection ecol = new EntryCollection(user, atomURL);
+        ecol.putEntry(areq, entry);
     }
-    
+
+
     /**
-     * Delete entry, URI like this /blog-name/entry/id
+     * Update resource specified by pathInfo using data from input stream.
+     * Expects pathInfo of form /blog-name/resource/path/name
      */
-    public void deleteEntry(AtomRequest areq) throws AtomException {
-        log.debug("Entering");
-        String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-        try {
-            if (pathInfo.length > 2) {
-                if (pathInfo[1].equals("entry")) // URI is /blogname/entry/entryid
-                {                    
-                    WeblogEntry rollerEntry = roller.getWeblogEntryManager().getWeblogEntry(pathInfo[2]);
-                    if (rollerEntry == null) {
-                        throw new AtomNotFoundException("cannot find specified entry/resource");
-                    }
-                    if (canEdit(rollerEntry)) {
-                        WeblogEntryManager mgr = roller.getWeblogEntryManager();                                                
-                        CacheManager.invalidate(rollerEntry.getWebsite());                        
-                        reindexEntry(rollerEntry);
-                        mgr.removeWeblogEntry(rollerEntry);
-                        log.debug("Deleted entry:" + rollerEntry.getAnchor());
-                        roller.flush();
-                        return;
-                    } 
-                } else if (pathInfo[1].equals("resource")) {
-                    String handle = pathInfo[0];
-                    Weblog website = roller.getWeblogManager().getWeblogByHandle(handle);
-                    if (website == null) {
-                        throw new AtomNotFoundException("cannot find specified weblog");
-                    }
-                    if (canEdit(website) && pathInfo.length > 1) {
-                        try {                            
-                            String path = filePathFromPathInfo(pathInfo);
-                            String fileName = path.substring(0, path.length() - ".media-link".length());
-                            FileManager fmgr = roller.getFileManager();
-                            fmgr.deleteFile(website, fileName);
-                            log.debug("Deleted resource: " + fileName);
-                        } catch (Exception e) {
-                            String msg = "ERROR in atom.deleteResource";
-                            log.error(msg,e);
-                            throw new AtomException(msg);
-                        }
-                        return;
-                    }               
-                }
-                throw new AtomNotAuthorizedException("ERROR not authorized to delete entry");
-            }
-            throw new AtomNotFoundException("cannot find specified entry/resource");
-            
-        } catch (WebloggerException re) {
-            throw new AtomException("deleting entry");
-        }
+    public void putMedia(AtomRequest areq) throws AtomException {
+        MediaCollection mcol = new MediaCollection(user, atomURL);
+        mcol.putMedia(areq);
     }
     
-    //-------------------------------------------------------------------- resources
+    
+    //----------------------------------------------------------------- delete
     
     /**
-     * Create new resource in generic collection (a Weblogger blog has only one).
-     * TODO: can we avoid saving temporary file?
-     * TODO: do we need to handle mutli-part MIME uploads?
-     * TODO: use Jakarta Commons File-upload?
+     * Delete entry, URI like this /blog-name/entry/id
      */
-    public String postMedia(AtomRequest areq, Entry entry)
-            throws AtomException {
+    public void deleteEntry(AtomRequest areq) throws AtomException {
         log.debug("Entering");
         String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-
-        try {
-            // get incoming slug from HTTP header
-            String slug = areq.getHeader("Slug");
-
-            Content content = (Content)entry.getContents().get(0); 
-            String contentType = content.getType();
-            InputStream is = areq.getInputStream();
-            String title = entry.getTitle() != null ? entry.getTitle() : slug;
-            
-            // authenticated client posted a weblog entry
-            File tempFile = null;
-            String handle = pathInfo[0];
-            FileManager fmgr = roller.getFileManager();
-            Weblog website = WebloggerFactory.getWeblogger().getWeblogManager().getWeblogByHandle(handle);
-            if (!canEdit(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to edit weblog: " + handle);
-            }
-            if (pathInfo.length > 1) {
-                // Save to temp file
-                String fileName = createFileName(website, 
-                    (slug != null) ? slug : Utilities.replaceNonAlphanumeric(title,' '), contentType);
-                try {
-                    tempFile = File.createTempFile(fileName, "tmp");
-                    FileOutputStream fos = new FileOutputStream(tempFile);
-                    Utilities.copyInputToOutput(is, fos);
-                    fos.close();
-                                        
-                    // Parse pathinfo to determine file path
-                    String path = filePathFromPathInfo(pathInfo);
-                    
-                    if (path.length() > 0) path = path + File.separator;
-                    FileInputStream fis = new FileInputStream(tempFile);  
-                    fmgr.saveFile(website, path + fileName, contentType, tempFile.length(), fis);
-                    fis.close();
-                    
-                    ThemeResource resource = fmgr.getFile(website, path + fileName);
-                    
-                    
-                    Entry mediaEntry = createAtomResourceEntry(website, resource);
-                    for (Iterator it = mediaEntry.getOtherLinks().iterator(); it.hasNext();) {
-                        Link link = (Link)it.next();
-                        if ("edit".equals(link.getRel())) {
-                            log.debug("Exiting");
-                            return link.getHrefResolved();
-                        }
-                    }
-                    log.error("ERROR: no edit link found in saved media entry");
-                    
-                } catch (FileIOException fie) {
-                    throw new AtomException(
-                        "File upload disabled, over-quota or other error", fie);
-                } catch (Exception e) {
-                    throw new AtomException(
-                        "Unexpected error during file upload", e);
-                } finally {
-                    if (tempFile != null) tempFile.delete();
-                }
-            }
-            throw new AtomException("Error saving media entry");
-        
-        } catch (WebloggerException re) {
-            throw new AtomException("Posting media", re);
-        } catch (IOException ioe) {
-            throw new AtomException("Posting media", ioe);
-        }
-    }
-    
-    /**
-     * Creates a file name for a file based on a weblog, title string and a 
-     * content-type. 
-     * 
-     * @param weblog      Weblog for which file name is being created
-     * @param title       Title to be used as basis for file name (or null)
-     * @param contentType Content type of file (must not be null)
-     * 
-     * If a title is specified, the method will apply the same create-anchor 
-     * logic we use for weblog entries to create a file name based on the title.
-     *
-     * If title is null, the base file name will be the weblog handle plus a 
-     * YYYYMMDDHHSS timestamp. 
-     *
-     * The extension will be formed by using the part of content type that
-     * comes after he slash. 
-     *
-     * For example:
-     *    weblog.handle = "daveblog"
-     *    title         = "Port Antonio"
-     *    content-type  = "image/jpg"
-     * Would result in port_antonio.jpg
-     *
-     * Another example:
-     *    weblog.handle = "daveblog"
-     *    title         = null
-     *    content-type  = "image/jpg"
-     * Might result in daveblog-200608201034.jpg
-     */
-    private String createFileName(Weblog weblog, String slug, String contentType) {
-        
-        if (weblog == null) throw new IllegalArgumentException("weblog cannot be null");
-        if (contentType == null) throw new IllegalArgumentException("contentType cannot be null");
-        
-        String fileName = null;
-        
-        // Determine the extension based on the contentType. This is a hack.
-        // The info we need to map from contentType to file extension is in 
-        // JRE/lib/content-type.properties, but Java Activation doesn't provide 
-        // a way to do a reverse mapping or to get at the data.
-        String[] typeTokens = contentType.split("/");
-        String ext = typeTokens[1];
-        
-        if (slug != null && !slug.trim().equals("")) {              
-            // We've got a title, so use it to build file name
-            StringTokenizer toker = new StringTokenizer(slug);
-            String tmp = null;
-            int count = 0;
-            while (toker.hasMoreTokens() && count < 5) {
-                String s = toker.nextToken();
-                s = s.toLowerCase();
-                tmp = (tmp == null) ? s : tmp + "_" + s;
-                count++;
+        if (pathInfo.length > 2) {
+            if (pathInfo[1].equals("entry")) // URI is /blogname/entry/entryid
+            {                    
+                EntryCollection ecol = new EntryCollection(user, atomURL);
+                ecol.deleteEntry(areq);
+
+            } else if (pathInfo[1].equals("resource")) {
+                MediaCollection mcol = new MediaCollection(user, atomURL);
+                mcol.deleteEntry(areq);
             }
-            if (!tmp.endsWith("." + ext)) {
-                fileName = tmp + "." + ext;
-            } else {
-                fileName = tmp;
-            }            
-        } else {            
-            // No title or text, so instead we'll use the item's date
-            // in YYYYMMDD format to form the file name
-            SimpleDateFormat sdf = new SimpleDateFormat();
-            sdf.applyPattern("yyyyMMddHHSS");
-            fileName = weblog.getHandle()+"-"+sdf.format(new Date())+"."+ext;
+            throw new AtomNotAuthorizedException("ERROR not authorized to delete entry");
         }
-        
-        return fileName;
+        throw new AtomNotFoundException("cannot find specified entry/resource");
     }
-    
-    
-    /**
-     * Update resource specified by pathInfo using data from input stream.
-     * Expects pathInfo of form /blog-name/resource/path/name
-     */
-    public void putMedia(AtomRequest areq) throws AtomException {
-       String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/");
-       String contentType = areq.getContentType();
-       try {
-            InputStream is = areq.getInputStream();
-     
-            // authenticated client posted a weblog entry
-            File tempFile = null;
-            String handle = pathInfo[0];
-            FileManager fmgr = roller.getFileManager();
-            WeblogManager wmgr = roller.getWeblogManager();
-            Weblog website = wmgr.getWeblogByHandle(handle);
-            if (!canEdit(website)) {
-                throw new AtomNotAuthorizedException("Not authorized to edit weblog: " + handle);
-            }
-            if (pathInfo.length > 1) {
-                // Save to temp file
-                try {
-                    tempFile = File.createTempFile(UUID.randomUUID().toString(), "tmp");
-                    FileOutputStream fos = new FileOutputStream(tempFile);
-                    Utilities.copyInputToOutput(is, fos);
-                    fos.close();
-                                        
-                    // Parse pathinfo to determine file path
-                    String path = filePathFromPathInfo(pathInfo);
-                    
-                    // Attempt to load file, to ensure it exists
-                    ThemeResource resource = fmgr.getFile(website, path);                    
-                    
-                    FileInputStream fis = new FileInputStream(tempFile);  
-                    fmgr.saveFile(website, path, contentType, tempFile.length(), fis);
-                    fis.close();
-                    
-                    log.debug("Exiting");
 
-                } catch (FileIOException fie) {
-                    throw new AtomException(
-                        "File upload disabled, over-quota or other error", fie);
-                } catch (Exception e) {
-                    throw new AtomException(
-                        "Unexpected error during file upload", e);
-                } finally {
-                    if (tempFile != null) tempFile.delete();
-                }
-            }
-            throw new AtomException("Incorrect path information");
-        
-        } catch (WebloggerException re) {
-            throw new AtomException("Posting media");
-        } catch (IOException ioe) {
-            throw new AtomException("Posting media", ioe);
-        }
-
-    }
-            
+    
     //------------------------------------------------------------------ URI testers
     
     /**
@@ -889,9 +343,9 @@
     /**
      * Return true if user is allowed to edit an entry.
      */
-    private boolean canEdit(WeblogEntry entry) {
+    public static boolean canEdit(User u, WeblogEntry entry) {
         try {
-            return entry.hasWritePermissions(this.user);
+            return entry.hasWritePermissions(u);
         } catch (Exception e) {
             log.error("Checking website.canSave()");
         }
@@ -901,9 +355,9 @@
     /**
      * Return true if user is allowed to create/edit weblog entries and file uploads in a website.
      */
-    private boolean canEdit(Weblog website) {
+    public static  boolean canEdit(User u, Weblog website) {
         try {
-            return website.hasUserPermission(this.user, WeblogPermission.POST);
+            return website.hasUserPermission(u, WeblogPermission.POST);
         } catch (Exception e) {
             log.error("Checking website.hasUserPermissions()");
         }
@@ -913,15 +367,15 @@
     /**
      * Return true if user is allowed to view an entry.
      */
-    private boolean canView(WeblogEntry entry) {
-        return canEdit(entry);
+    public static  boolean canView(User u, WeblogEntry entry) {
+        return canEdit(u, entry);
     }
     
     /**
      * Return true if user is allowed to view a website.
      */
-    private boolean canView(Weblog website) {
-        return canEdit(website);
+    public static  boolean canView(User u, Weblog website) {
+        return canEdit(u, website);
     }
     
     //-------------------------------------------------------------- authentication
@@ -1015,260 +469,15 @@
         if (valid) return userID;
         return null;
     }
-    
-    //----------------------------------------------------------- internal utilities
-    
-    /**
-     * Create a Rome Atom entry based on a Weblogger entry.
-     * Content is escaped.
-     * Link is stored as rel=alternate link.
-     */
-    private Entry createAtomEntry(WeblogEntry entry) {
-        Entry atomEntry = new Entry();
-        
-        String absUrl = WebloggerRuntimeConfig.getAbsoluteContextURL();
-        atomEntry.setId(        absUrl + entry.getPermaLink());
-        atomEntry.setTitle(     entry.getTitle());
-        atomEntry.setPublished( entry.getPubTime());
-        atomEntry.setUpdated(   entry.getUpdateTime());
-        
-        Content content = new Content();
-        content.setType(Content.HTML);
-        content.setValue(entry.getText());
-        List contents = new ArrayList();
-        contents.add(content);
-        
-        atomEntry.setContents(contents);
-        
-        if (StringUtils.isNotEmpty(entry.getSummary())) {
-            Content summary = new Content();
-            summary.setType(Content.HTML);
-            summary.setValue(entry.getSummary());
-            atomEntry.setSummary(summary);
-        }
-        
-        User creator = entry.getCreator();
-        Person author = new Person();
-        author.setName(         creator.getUserName());
-        author.setEmail(        creator.getEmailAddress());
-        atomEntry.setAuthors(   Collections.singletonList(author));
-        
-        // Add Atom category for Weblogger category, using category scheme
-        List categories = new ArrayList();
-        Category atomCat = new Category();
-        atomCat.setScheme(RollerAtomService.getWeblogCategoryScheme(entry.getWebsite()));
-        atomCat.setTerm(entry.getCategory().getPath().substring(1));
-        categories.add(atomCat);
-        
-        // Add Atom categories for each Weblogger tag with null scheme
-        for (Iterator tagit = entry.getTags().iterator(); tagit.hasNext();) {
-            WeblogEntryTag tag = (WeblogEntryTag) tagit.next();
-            Category newcat = new Category();
-            newcat.setTerm(tag.getName());
-            categories.add(newcat);
-        }        
-        atomEntry.setCategories(categories);
-        
-        Link altlink = new Link();
-        altlink.setRel("alternate");
-        altlink.setHref(absUrl + entry.getPermaLink());
-        List altlinks = new ArrayList();
-        altlinks.add(altlink);
-        atomEntry.setAlternateLinks(altlinks);
-        
-        Link editlink = new Link();
-        editlink.setRel("edit");
-        editlink.setHref(
-                atomURL
-                +"/"+entry.getWebsite().getHandle() + "/entry/" + entry.getId());
-        List otherlinks = new ArrayList();
-        otherlinks.add(editlink);
-        atomEntry.setOtherLinks(otherlinks);
-        
-        List modules = new ArrayList();
-        AppModule app = new AppModuleImpl();
-        app.setDraft(!WeblogEntry.PUBLISHED.equals(entry.getStatus()));
-        app.setEdited(entry.getUpdateTime());
-        modules.add(app);
-        atomEntry.setModules(modules);
-        
-        return atomEntry;
-    }
-    
-    private Entry createAtomResourceEntry(Weblog website, ThemeResource file) {
-        String absUrl = WebloggerRuntimeConfig.getAbsoluteContextURL();
-        String filePath = 
-            file.getPath().startsWith("/") ? file.getPath().substring(1) : file.getPath();
-        String editURI = 
-                atomURL+"/"+website.getHandle()
-                + "/resource/" + filePath + ".media-link";
-        String editMediaURI = 
-                atomURL+"/"+ website.getHandle()
-                + "/resource/" + filePath;
-        URLStrategy urlStrategy = WebloggerFactory.getWeblogger().getUrlStrategy();
-        String viewURI = urlStrategy.getWeblogResourceURL(website, filePath, true);
-        
-        FileTypeMap map = FileTypeMap.getDefaultFileTypeMap();
-        // TODO: figure out why PNG is missing from Java MIME types
-        if (map instanceof MimetypesFileTypeMap) {
-            try {
-                ((MimetypesFileTypeMap)map).addMimeTypes("image/png png PNG");
-            } catch (Exception ignored) {}
-        }
-        String contentType = map.getContentType(file.getName());
-        
-        Entry entry = new Entry();
-        entry.setId(editMediaURI);
-        entry.setTitle(file.getName());
-        entry.setUpdated(new Date(file.getLastModified()));
-        
-        List otherlinks = new ArrayList();        
-        entry.setOtherLinks(otherlinks);
-        Link editlink = new Link();
-            editlink.setRel("edit");
-            editlink.setHref(editURI);        
-            otherlinks.add(editlink);            
-        Link editMedialink = new Link();
-            editMedialink.setRel("edit-media");
-            editMedialink.setHref(editMediaURI);        
-            otherlinks.add(editMedialink);
-        
-        Content content = new Content();
-        content.setSrc(viewURI);
-        content.setType(contentType);
-        List contents = new ArrayList();
-        contents.add(content);
-        entry.setContents(contents);
-        
-        List modules = new ArrayList();
-        AppModule app = new AppModuleImpl();
-        app.setDraft(false);
-        app.setEdited(entry.getUpdated());
-        modules.add(app);
-        entry.setModules(modules);
-        
-        return entry;
-    }
-    
-    /**
-     * Copy fields from ROME entry to Weblogger entry.
-     */
-    private void copyToRollerEntry(Entry entry, WeblogEntry rollerEntry) throws WebloggerException {
-        
-        Timestamp current = new Timestamp(System.currentTimeMillis());
-        Timestamp pubTime = current;
-        Timestamp updateTime = current;
-        if (entry.getPublished() != null) {
-            pubTime = new Timestamp( entry.getPublished().getTime() );
-        }
-        if (entry.getUpdated() != null) {
-            updateTime = new Timestamp( entry.getUpdated().getTime() );
-        }
-        rollerEntry.setTitle(entry.getTitle());
-        if (entry.getContents() != null && entry.getContents().size() > 0) {
-            Content content = (Content)entry.getContents().get(0);
-            rollerEntry.setText(content.getValue());
-        }
-        if (entry.getSummary() != null) {
-            rollerEntry.setSummary(entry.getSummary().getValue());
-        }
-        rollerEntry.setPubTime(pubTime);
-        rollerEntry.setUpdateTime(updateTime);
-        
-        AppModule control =
-                (AppModule)entry.getModule(AppModule.URI);
-        if (control!=null && control.getDraft()) {
-            rollerEntry.setStatus(WeblogEntry.DRAFT);
-        } else {
-            rollerEntry.setStatus(WeblogEntry.PUBLISHED);
-        }
-                
-        // Process incoming categories:
-        // Atom categories with weblog-level scheme are Weblogger categories.
-        // Atom supports multiple cats, but Weblogger supports one/entry
-        // so here we take accept the first category that exists.
-        List categories = entry.getCategories();
-        if (categories != null && categories.size() > 0) {
-            for (int i=0; i<categories.size(); i++) {
-                Category cat = (Category)categories.get(i);
-                
-                if (cat.getScheme() != null && cat.getScheme().equals(
-                        RollerAtomService.getWeblogCategoryScheme(rollerEntry.getWebsite()))) {
-                    String catString = cat.getTerm();
-                    if (catString != null) {
-                        WeblogCategory rollerCat =
-                                roller.getWeblogEntryManager().getWeblogCategoryByPath(
-                                rollerEntry.getWebsite(), catString);
-                        if (rollerCat != null) {
-                            // Found a valid category, so break out
-                            rollerEntry.setCategory(rollerCat);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-        if (rollerEntry.getCategory() == null) {
-            // Didn't find a category? Fall back to the default Blogger API category.
-            rollerEntry.setCategory(rollerEntry.getWebsite().getBloggerCategory());
-        }
-        
-        // Now process incoming categories that are tags:
-        // Atom categories with no scheme are considered tags.
-        String tags = "";
-        if (categories != null && categories.size() > 0) {
-            for (int i=0; i<categories.size(); i++) {
-                Category cat = (Category)categories.get(i);            
-                if (cat.getScheme() == null) {
-                    tags = tags + " " + cat.getTerm();
-                }                
-            }
-        }
-        rollerEntry.setTagsAsString(tags);        
-    }
-    
-    public Categories getCategories(AtomRequest arg0) throws AtomException {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 
-    private String filePathFromPathInfo(String[] pathInfo) {
-        String path = null;
-        if (pathInfo.length > 2) {
-            for (int i = 2; i < pathInfo.length; i++) {
-                if (path != null && path.length() > 0)
-                    path = path + File.separator + pathInfo[i];
-                else
-                    path = pathInfo[i];
-            }
-        } if (pathInfo.length == 2) {
-            path = "";
-        }
-        return path;
-    }
     
-    private void reindexEntry(WeblogEntry entry) throws WebloggerException {
-        IndexManager manager = roller.getIndexManager();
-        
-        // TODO: figure out what's up here and at WeblogEntryFormAction line 696
-        //manager.removeEntryIndexOperation(entry);
-        
-        // if published, index the entry
-        if (entry.isPublished()) {
-            manager.addEntryReIndexOperation(entry);
-        }
-    }
-    
-    private void oneSecondThrottle() {
+    public static void oneSecondThrottle() {
         // Throttle one entry per second per weblog because time-
         // stamp in MySQL and other DBs has only 1 sec resolution
-        try { 
-            synchronized (getClass()) { 
+        if (throttle) try { 
+            synchronized (RollerAtomHandler.class) { 
                 Thread.sleep(1000); 
             }  
         } catch (Exception ignored) {} 
     }
-
 }
-
-
-