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) {} } - } - - -
