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 2006/08/06 17:43:27 UTC
svn commit: r429139 [2/2] - in /incubator/roller/branches/roller_3.0: ./
metadata/database/ sandbox/jdobackend/src/org/apache/roller/business/jdo/
src/org/apache/roller/business/ src/org/apache/roller/business/hibernate/
src/org/apache/roller/model/ sr...
Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/atomprotocol/RollerAtomHandler.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/atomprotocol/RollerAtomHandler.java?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/atomprotocol/RollerAtomHandler.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/atomprotocol/RollerAtomHandler.java Sun Aug 6 08:43:26 2006
@@ -1,18 +1,20 @@
/*
- * Copyright 2005 David M Johnson (For RSS and Atom In Action)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
package org.apache.roller.webservices.atomprotocol;
import java.io.File;
import java.io.FileInputStream;
@@ -25,6 +27,7 @@
import java.util.List;
import java.util.StringTokenizer;
import java.util.Collections;
+import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
@@ -50,33 +53,55 @@
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.feed.atom.Person;
+import java.io.IOException;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
import javax.activation.FileTypeMap;
+import org.apache.commons.lang.StringUtils;
import org.apache.roller.RollerException;
import org.apache.roller.config.RollerConfig;
import org.apache.roller.config.RollerRuntimeConfig;
import org.apache.roller.model.WeblogManager;
+import org.apache.roller.pojos.RollerPropertyData;
+import org.apache.roller.util.URLUtilities;
import org.apache.roller.util.cache.CacheManager;
/**
* Roller's Atom Protocol implementation.
* <pre>
- * Here are the URIs suppored:
+ * Each Roller workspace has two collections, one that accepts entries and
+ * that accepts everything. The entries collection represents the weblog
+ * entries in a single weblog and the everything collection represents that
+ * weblog's uploaded-files.
+ *
+ * Here are the APP URIs suppored by Roller:
+ *
+ * /roller-services/app
+ * Introspection doc
+ *
+ * /roller-services/app/<weblog-handle>/entries
+ * Entry collection for a blog
+ *
+ * /roller-services/app/<weblog-handle>/entries/<offset>
+ * Entry collection for a blog, with offset
+ *
+ * /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
+ *
+ * /roller-services/app/<weblog-handle>/resources/<offset>
+ * Resource collection for a blog, with offset
+ *
+ * /roller-services/app/<weblog-handle>/resource/*.media-link<name>
+ * Individual resource metadata (i.e. edit URI)
+ *
+ * /roller-services/app/<weblog-handle>/resource/<name>
+ * Individual resource data (i.e. media-edit URI)
*
- * URI type URI form Handled by
- * -------- -------- ----------
- * Introspection URI / getIntrosection()
- * Collection URI /blog-name/<collection-name> getCollection()
- * Member URI /blog-name/<object-name> post<object-name>()
- * Member URI /blog-name/<object-name>/id get<object-name>()
- * Member URI /blog-name/<object-name>/id put<object-name>()
- * Member URI /blog-name/<object-name>/id delete<object-name>()
- *
- * Until group blogging is supported weblogHandle == blogname.
- *
- * Collection-names Object-names
- * ---------------- ------------
- * entries entry
- * resources resource
* </pre>
*
* @author David M Johnson
@@ -106,15 +131,14 @@
mRollerContext = RollerContext.getRollerContext();
// TODO: decide what to do about authentication, is WSSE going to fly?
- //mUsername = authenticateWSSE(request);
- String mUsername = authenticateBASIC(request);
-
- if (mUsername != null) {
+ //String userName = authenticateWSSE(request);
+ String userName = authenticateBASIC(request);
+ if (userName != null) {
try {
- this.user = mRoller.getUserManager().getUserByUserName(mUsername);
- } catch (Exception e) {
- mLogger.error("ERROR: setting user", e);
- }
+ this.user = mRoller.getUserManager().getUserByUserName(userName);
+ } catch (Exception neverHappen) {
+ mLogger.debug("ERROR: getting user", neverHappen);
+ }
}
}
@@ -122,7 +146,11 @@
* Return weblogHandle of authenticated user or null if there is none.
*/
public String getAuthenticatedUsername() {
- return this.user.getUserName();
+ String ret = null;
+ if (this.user != null) {
+ ret = user.getUserName();
+ }
+ return ret;
}
//---------------------------------------------------------------- introspection
@@ -131,37 +159,65 @@
* Return Atom service document for site, getting blog-name from pathInfo.
* The workspace will contain collections for entries, categories and resources.
*/
- public AtomService getIntrospection(String[] pathInfo) throws Exception {
- if (pathInfo.length == 0) {
- String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
- AtomService service = new AtomService();
- List perms = mRoller.getUserManager().getAllPermissions(user);
- if (perms != null) {
- for (Iterator iter=perms.iterator(); iter.hasNext();) {
- PermissionsData perm = (PermissionsData)iter.next();
- String handle = perm.getWebsite().getHandle();
- AtomService.Workspace workspace = new AtomService.Workspace();
- workspace.setTitle(Utilities.removeHTML(perm.getWebsite().getName()));
- service.addWorkspace(workspace);
-
- AtomService.Collection entryCol = new AtomService.Collection();
- entryCol.setTitle("Weblog Entries");
- entryCol.setMemberType("entry");
- entryCol.setHref(absUrl + "/app/"+handle+"/entries");
- workspace.addCollection(entryCol);
-
- AtomService.Collection uploadCol = new AtomService.Collection();
- uploadCol.setTitle("Media Files");
- uploadCol.setMemberType("media");
- uploadCol.setHref(absUrl + "/app/"+handle+"/resources");
- workspace.addCollection(uploadCol);
- }
+ public AtomService getIntrospection() throws AtomException {
+ AtomService service = new AtomService();
+ List perms = null;
+ try {
+ perms = mRoller.getUserManager().getAllPermissions(user);
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: getting user's weblogs", re);
+ }
+ String accept = null;
+ try {
+ accept = getAcceptedContentTypeRange();
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: getting site's accept range", re);
+ }
+ if (perms != null) {
+ for (Iterator iter=perms.iterator(); iter.hasNext();) {
+ PermissionsData perm = (PermissionsData)iter.next();
+ String handle = perm.getWebsite().getHandle();
+ AtomService.Workspace workspace = new AtomService.Workspace();
+ workspace.setTitle(Utilities.removeHTML(perm.getWebsite().getName()));
+ service.addWorkspace(workspace);
+
+ AtomService.Collection entryCol = new AtomService.Collection();
+ entryCol.setTitle("Weblog Entries");
+ entryCol.setAccept("entry");
+ entryCol.setHref(URLUtilities.getAtomProtocolURL(true)+"/"+handle+"/entries");
+ workspace.addCollection(entryCol);
+
+
+ AtomService.Collection uploadCol = new AtomService.Collection();
+ uploadCol.setTitle("Media Files");
+ uploadCol.setAccept(accept);
+ uploadCol.setHref(URLUtilities.getAtomProtocolURL(true)+"/"+handle+"/resources");
+ workspace.addCollection(uploadCol);
}
- return service;
}
- throw new Exception("ERROR: bad URL in getIntrospection()");
+ return service;
}
+ /**
+ * Build accept range by taking things that appear to be content-type rules
+ * from site's file-upload allowed extensions.
+ */
+ private String getAcceptedContentTypeRange() throws RollerException {
+ StringBuffer sb = new StringBuffer();
+ Roller roller = RollerFactory.getRoller();
+ Map config = roller.getPropertiesManager().getProperties();
+ String allows = ((RollerPropertyData)config.get("uploads.types.allowed")).getValue();
+ String[] rules = StringUtils.split(StringUtils.deleteWhitespace(allows), ",");
+ for (int i=0; i<rules.length; i++) {
+ if (rules[i].indexOf("/") == -1) continue;
+ if (sb.length() != 0) {
+ sb.append(",");
+ }
+ sb.append(rules[i]);
+ }
+ return sb.toString();
+ }
+
//----------------------------------------------------------------- collections
/**
@@ -174,10 +230,10 @@
* /<blog-name>/resources/offset
* </pre>
*/
- public Feed getCollection(String[] pathInfo) throws Exception {
+ public Feed getCollection(String[] pathInfo) throws AtomException {
int start = 0;
if (pathInfo.length > 2) {
- try {
+ try {
String s = pathInfo[2].trim();
start = Integer.parseInt(s);
} catch (Throwable t) {
@@ -189,208 +245,333 @@
} else if (pathInfo.length > 0 && pathInfo[1].equals("resources")) {
return getCollectionOfResources(pathInfo, start, mMaxEntries);
}
- throw new Exception("ERROR: bad URL in getCollection()");
+ throw new AtomNotFoundException("ERROR: cannot find collection specified");
}
/**
* Helper method that returns collection of entries, called by getCollection().
*/
public Feed getCollectionOfEntries(
- String[] pathInfo, int start, int max) throws Exception {
- String handle = pathInfo[0];
- String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- List entries = null;
- if (canView(website)) {
- entries = mRoller.getWeblogManager().getWeblogEntries(
- website, // website
- null,
- null, // startDate
- null, // endDate
- null, // catName
- null, // status
- "updateTime", // sortby
-null, start, // offset (for range paging)
- max + 1); // locale
- Feed feed = new Feed();
- feed.setTitle("Entries for blog[" + handle + "]");
- List atomEntries = new ArrayList();
- int count = 0;
- for (Iterator iter = entries.iterator(); iter.hasNext() && count < mMaxEntries; count++) {
- WeblogEntryData rollerEntry = (WeblogEntryData)iter.next();
- atomEntries.add(createAtomEntry(rollerEntry));
- }
- List links = new ArrayList();
- if (entries.size() > max) { // add next link
- int nextOffset = start + max;
- String url = absUrl + "/app/" + 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 = absUrl + "/app/" +website.getHandle() + "/entries/" + prevOffset;
- Link prevLink = new Link();
- prevLink.setRel("previous");
- prevLink.setHref(url);
- links.add(prevLink);
- }
- if (links.size() > 0) feed.setOtherLinks(links);
- feed.setEntries(atomEntries);
- return feed;
+ String[] pathInfo, int start, int max) throws AtomException {
+ try {
+ String handle = pathInfo[0];
+ String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
+ WebsiteData website =
+ mRoller.getUserManager().getWebsiteByHandle(handle);
+ if (website == null) {
+ throw new AtomNotFoundException("ERROR: cannot find specified weblog");
+ }
+ List entries = null;
+ if (canView(website)) {
+ entries = mRoller.getWeblogManager().getWeblogEntries(
+ website, // website
+ null, // user
+ null, // startDate
+ null, // endDate
+ null, // catName
+ null, // status
+ "updateTime", // sortby
+ null, // locale
+ start, // offset (for range paging)
+ max + 1); // maxEntries
+ Feed feed = new Feed();
+ feed.setId(URLUtilities.getAtomProtocolURL(true)
+ +"/"+website.getHandle() + "/entries/" + start);
+ feed.setTitle("Entries for blog[" + handle + "]");
+ List atomEntries = new ArrayList();
+ int count = 0;
+ for (Iterator iter = entries.iterator(); iter.hasNext() && count < mMaxEntries; count++) {
+ WeblogEntryData rollerEntry = (WeblogEntryData)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 = URLUtilities.getAtomProtocolURL(true)+"/"
+ + 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 = URLUtilities.getAtomProtocolURL(true)+"/"
+ +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);
+ return feed;
+ }
+ throw new AtomNotAuthorizedException("ERROR: not authorized to access website");
+
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: getting entry collection");
}
- throw new Exception("ERROR: not authorized");
}
/**
* Helper method that returns collection of resources, called by getCollection().
*/
public Feed getCollectionOfResources(
- String[] pathInfo, int start, int max) throws Exception {
- String handle = pathInfo[0];
- String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- FileManager fmgr = mRoller.getFileManager();
- File[] files = fmgr.getFiles(website.getHandle());
- if (canView(website)) {
- Feed feed = new Feed();
- List atomEntries = new ArrayList();
- int count = 0;
- if (files != null && start < files.length) {
- for (int i=start; i<(start + max) && i<(files.length); i++) {
- Entry entry = createAtomResourceEntry(website, files[i]);
+ String[] pathInfo, int start, int max) throws AtomException {
+ try {
+ String handle = pathInfo[0];
+ String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
+ WebsiteData website =
+ mRoller.getUserManager().getWebsiteByHandle(handle);
+ if (website == null) {
+ throw new AtomNotFoundException(
+ "ERROR: cannot find specified weblog");
+ }
+ FileManager fmgr = mRoller.getFileManager();
+ File[] files = fmgr.getFiles(website.getHandle());
+
+ if (canView(website)) {
+ Feed feed = new Feed();
+ feed.setId(URLUtilities.getAtomProtocolURL(true)
+ +"/"+website.getHandle() + "/entries/" + start);
+ SortedSet sortedSet = new TreeSet(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ File f1 = (File)o1;
+ File f2 = (File)o2;
+ if (f1.lastModified() < f2.lastModified()) return 1;
+ else if (f1.lastModified() == f2.lastModified()) return 0;
+ else return -1;
+ }
+ public boolean equals(Object obj) {
+ return false;
+ }
+ });
+ List atomEntries = new ArrayList();
+ if (files != null && start < files.length) {
+ for (int i=0; i<files.length; i++) {
+ sortedSet.add(files[i]);
+ }
+ }
+ int count = 0;
+ File[] sortedArray = (File[])sortedSet.toArray(new File[sortedSet.size()]);
+ for (int i=start; i<(start + max) && i<(sortedArray.length); i++) {
+ Entry entry = createAtomResourceEntry(website, sortedArray[i]);
atomEntries.add(entry);
+ if (count == 0) {
+ // first entry is most recent
+ feed.setUpdated(entry.getUpdated());
+ }
count++;
}
+ if (start + count < files.length) { // add next link
+ int nextOffset = start + max;
+ String url = URLUtilities.getAtomProtocolURL(true)
+ +"/"+ website.getHandle() + "/resources/" + nextOffset;
+ Link nextLink = new Link();
+ nextLink.setRel("next");
+ nextLink.setHref(url);
+ List next = new ArrayList();
+ next.add(nextLink);
+ feed.setOtherLinks(next);
+ }
+ if (start > 0) { // add previous link
+ int prevOffset = start > max ? start - max : 0;
+ String url = URLUtilities.getAtomProtocolURL(true)
+ +"/"+website.getHandle() + "/resources/" + prevOffset;
+ Link prevLink = new Link();
+ prevLink.setRel("previous");
+ prevLink.setHref(url);
+ List prev = new ArrayList();
+ prev.add(prevLink);
+ feed.setOtherLinks(prev);
+ }
+ feed.setEntries(atomEntries);
+ return feed;
}
- if (start + count < files.length) { // add next link
- int nextOffset = start + max;
- String url = absUrl + "/app/" + website.getHandle() + "/resources/" + nextOffset;
- Link nextLink = new Link();
- nextLink.setRel("next");
- nextLink.setHref(url);
- List next = new ArrayList();
- next.add(nextLink);
- feed.setOtherLinks(next);
- }
- if (start > 0) { // add previous link
- int prevOffset = start > max ? start - max : 0;
- String url = absUrl + "/app/" +website.getHandle() + "/resources/" + prevOffset;
- Link prevLink = new Link();
- prevLink.setRel("previous");
- prevLink.setHref(url);
- List prev = new ArrayList();
- prev.add(prevLink);
- feed.setOtherLinks(prev);
- }
- feed.setEntries(atomEntries);
- return feed;
+ throw new AtomNotAuthorizedException(
+ "ERROR: not authorized to access website");
+
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: getting resource collection");
}
- throw new Exception("ERROR: not authorized");
- }
+ }
//--------------------------------------------------------------------- entries
/**
* Create entry in the entry collection (a Roller blog has only one).
*/
- public Entry postEntry(String[] pathInfo, Entry entry) throws Exception {
- // authenticated client posted a weblog entry
- String handle = pathInfo[0];
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- if (canEdit(website)) {
- // Save it and commit it
- WeblogManager mgr = mRoller.getWeblogManager();
- WeblogEntryData rollerEntry = createRollerEntry(website, entry);
- rollerEntry.setCreator(this.user);
- mgr.saveWeblogEntry(rollerEntry);
- mRoller.flush();
-
- // Throttle one entry per second
- // (MySQL timestamp has 1 sec resolution, damnit)
- Thread.sleep(1000);
+ public Entry postEntry(String[] pathInfo, Entry entry) throws AtomException {
+ try {
+ // authenticated client posted a weblog entry
+ String handle = pathInfo[0];
+ WebsiteData website =
+ mRoller.getUserManager().getWebsiteByHandle(handle);
+ if (website == null) {
+ throw new AtomNotFoundException("ERROR: cannot find specified weblog");
+ }
+ if (canEdit(website)) {
+ // Save it and commit it
+ WeblogManager mgr = mRoller.getWeblogManager();
+ WeblogEntryData rollerEntry = createRollerEntry(website, entry);
+ rollerEntry.setCreator(this.user);
+ mgr.saveWeblogEntry(rollerEntry);
+ mRoller.flush();
+
+ // Throttle one entry per second
+ // (MySQL timestamp has 1 sec resolution, damnit)
+ try { Thread.sleep(1000); } catch (Exception ignored) {}
+
+ CacheManager.invalidate(website);
+ if (rollerEntry.isPublished()) {
+ mRoller.getIndexManager().addEntryReIndexOperation(rollerEntry);
+ }
+ return createAtomEntry(rollerEntry);
+ }
+ throw new AtomNotAuthorizedException(
+ "ERROR: not authorized to access website");
- CacheManager.invalidate(website);
- if (rollerEntry.isPublished()) {
- mRoller.getIndexManager().addEntryReIndexOperation(rollerEntry);
- }
- return createAtomEntry(rollerEntry);
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: posting entry");
}
- throw new Exception("ERROR not authorized to edit website");
}
/**
* Retrieve entry, URI like this /blog-name/entry/id
*/
- public Entry getEntry(String[] pathInfo) throws Exception {
- if (pathInfo.length == 3) // URI is /blogname/entries/entryid
- {
- WeblogEntryData entry =
- mRoller.getWeblogManager().getWeblogEntry(pathInfo[2]);
- if (entry != null && !canView(entry)) {
- throw new Exception("ERROR not authorized to view entry");
- } else if (entry != null) {
- return createAtomEntry(entry);
+ public Entry getEntry(String[] pathInfo) throws AtomException {
+ try {
+ if (pathInfo.length == 3) // URI is /blogname/entries/entryid
+ {
+ if (pathInfo[1].equals("entry")) {
+ WeblogEntryData entry =
+ mRoller.getWeblogManager().getWeblogEntry(pathInfo[2]);
+ if (entry == null) {
+ throw new AtomNotFoundException(
+ "ERROR: cannot find specified entry/resource");
+ }
+ if (!canView(entry)) {
+ throw new AtomNotAuthorizedException(
+ "ERROR: not authorized to view entry");
+ } else {
+ return createAtomEntry(entry);
+ }
+ } else if (pathInfo[1].equals("resource") && pathInfo[2].endsWith(".media-link")) {
+ String fileName =
+ pathInfo[2].substring(0, pathInfo[2].length() - ".media-link".length());
+ String handle = pathInfo[0];
+ WebsiteData website =
+ mRoller.getUserManager().getWebsiteByHandle(handle);
+ String uploadPath =
+ RollerFactory.getRoller().getFileManager().getUploadUrl();
+ File resource =
+ new File(uploadPath + File.separator + fileName);
+ return createAtomResourceEntry(website, resource);
+ }
}
- return null;
+ throw new AtomNotFoundException(
+ "ERROR: cannot find specified entry/resource");
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: getting entry");
}
- throw new Exception("ERROR: bad URI");
}
/**
* Update entry, URI like this /blog-name/entry/id
*/
- public Entry putEntry(String[] pathInfo, Entry entry) throws Exception {
- if (pathInfo.length == 3) // URI is /blogname/entries/entryid
- {
- WeblogEntryData rollerEntry =
+ public Entry putEntry(String[] pathInfo, Entry entry) throws AtomException {
+ try {
+ if (pathInfo.length == 3) // URI is /blogname/entries/entryid
+ {
+ WeblogEntryData rollerEntry =
mRoller.getWeblogManager().getWeblogEntry(pathInfo[2]);
- if (canEdit(rollerEntry)) {
- WeblogManager mgr = mRoller.getWeblogManager();
-
- WeblogEntryData rawUpdate = createRollerEntry(rollerEntry.getWebsite(), entry);
- rollerEntry.setPubTime(rawUpdate.getPubTime());
- rollerEntry.setUpdateTime(rawUpdate.getUpdateTime());
- rollerEntry.setText(rawUpdate.getText());
- rollerEntry.setStatus(rawUpdate.getStatus());
- rollerEntry.setCategory(rawUpdate.getCategory());
- rollerEntry.setTitle(rawUpdate.getTitle());
-
- mgr.saveWeblogEntry(rollerEntry);
- mRoller.flush();
-
- CacheManager.invalidate(rollerEntry.getWebsite());
- if (rollerEntry.isPublished()) {
- mRoller.getIndexManager().addEntryReIndexOperation(rollerEntry);
- }
- return createAtomEntry(rollerEntry);
+ if (rollerEntry == null) {
+ throw new AtomNotFoundException(
+ "ERROR: cannot find specified entry/resource");
+ }
+ if (canEdit(rollerEntry)) {
+ WeblogManager mgr = mRoller.getWeblogManager();
+
+ WeblogEntryData rawUpdate = createRollerEntry(rollerEntry.getWebsite(), entry);
+ rollerEntry.setPubTime(rawUpdate.getPubTime());
+ rollerEntry.setUpdateTime(rawUpdate.getUpdateTime());
+ rollerEntry.setText(rawUpdate.getText());
+ rollerEntry.setStatus(rawUpdate.getStatus());
+ rollerEntry.setCategory(rawUpdate.getCategory());
+ rollerEntry.setTitle(rawUpdate.getTitle());
+
+ mgr.saveWeblogEntry(rollerEntry);
+ mRoller.flush();
+
+ CacheManager.invalidate(rollerEntry.getWebsite());
+ if (rollerEntry.isPublished()) {
+ mRoller.getIndexManager().addEntryReIndexOperation(rollerEntry);
+ }
+ return createAtomEntry(rollerEntry);
+ }
+ throw new AtomNotAuthorizedException("ERROR not authorized to update entry");
}
- throw new Exception("ERROR not authorized to put entry");
+ throw new AtomNotFoundException("ERROR: cannot find specified entry/resource");
+
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: updating entry");
}
- throw new Exception("ERROR: bad URI");
}
/**
* Delete entry, URI like this /blog-name/entry/id
*/
- public void deleteEntry(String[] pathInfo) throws Exception {
- if (pathInfo.length == 3) // URI is /blogname/entries/entryid
- {
- WeblogEntryData rollerEntry =
- mRoller.getWeblogManager().getWeblogEntry(pathInfo[2]);
- if (canEdit(rollerEntry)) {
- WeblogManager mgr = mRoller.getWeblogManager();
- mgr.removeWeblogEntry(rollerEntry);
- mRoller.flush();
- CacheManager.invalidate(rollerEntry.getWebsite());
- mRoller.getIndexManager().removeEntryIndexOperation(rollerEntry);
- return;
+ public void deleteEntry(String[] pathInfo) throws AtomException {
+ try {
+ if (pathInfo.length == 3) // URI is /blogname/entry/entryid
+ {
+ if (pathInfo[1].equals("entry")) {
+ WeblogEntryData rollerEntry = mRoller.getWeblogManager().getWeblogEntry(pathInfo[2]);
+ if (rollerEntry == null) {
+ throw new AtomNotFoundException("ERROR: cannot find specified entry/resource");
+ }
+ if (canEdit(rollerEntry)) {
+ WeblogManager mgr = mRoller.getWeblogManager();
+ mgr.removeWeblogEntry(rollerEntry);
+ mRoller.flush();
+ CacheManager.invalidate(rollerEntry.getWebsite());
+ mRoller.getIndexManager().removeEntryIndexOperation(rollerEntry);
+ return;
+ }
+ } else if (pathInfo[1].equals("resource") && pathInfo[2].endsWith(".media-link")) {
+ String handle = pathInfo[0];
+ WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
+ if (website == null) {
+ throw new AtomNotFoundException("ERROR: cannot find specified weblog");
+ }
+ if (canEdit(website) && pathInfo.length > 1) {
+ try {
+ String fileName =
+ pathInfo[2].substring(0, pathInfo[2].length() - ".media-link".length());
+ FileManager fmgr = mRoller.getFileManager();
+ fmgr.deleteFile(website.getHandle(), fileName);
+ } catch (Exception e) {
+ String msg = "ERROR in atom.deleteResource";
+ mLogger.error(msg,e);
+ throw new AtomException(msg);
+ }
+ return;
+ }
+ }
+ throw new AtomNotAuthorizedException("ERROR not authorized to delete entry");
}
- throw new Exception("ERROR not authorized to delete entry");
+ throw new AtomNotFoundException("ERROR: cannot find specified entry/resource");
+
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: deleting entry");
}
- throw new Exception("ERROR: bad URI");
}
//-------------------------------------------------------------------- resources
@@ -401,93 +582,69 @@
* TODO: do we need to handle mutli-part MIME uploads?
* TODO: use Jakarta Commons File-upload?
*/
- public Entry postMedia(String[] pathInfo,
+ public Entry postMedia(String[] pathInfo,
String name, String contentType, InputStream is)
- throws Exception {
- // authenticated client posted a weblog entry
- File tempFile = null;
- RollerMessages msgs = new RollerMessages();
- String handle = pathInfo[0];
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- if (canEdit(website) && pathInfo.length > 1) {
- // save to temp file
- if (name == null) {
- throw new Exception("ERROR[postResource]: No 'name' present in HTTP headers");
- }
- try {
- FileManager fmgr = mRoller.getFileManager();
- tempFile = File.createTempFile(name,"tmp");
- FileOutputStream fos = new FileOutputStream(tempFile);
- Utilities.copyInputToOutput(is, fos);
- fos.close();
-
- // If save is allowed by Roller system-wide policies
- if (fmgr.canSave(website.getHandle(), name, tempFile.length(), msgs)) {
- // Then save the file
- FileInputStream fis = new FileInputStream(tempFile);
- fmgr.saveFile(website.getHandle(), name, tempFile.length(), fis);
- fis.close();
-
- File resource = new File(fmgr.getUploadDir() + File.separator + name);
- return createAtomResourceEntry(website, resource);
+ throws AtomException {
+ try {
+ // authenticated client posted a weblog entry
+ File tempFile = null;
+ RollerMessages msgs = new RollerMessages();
+ String handle = pathInfo[0];
+ WebsiteData website =
+ mRoller.getUserManager().getWebsiteByHandle(handle);
+ if (canEdit(website) && pathInfo.length > 1) {
+ // save to temp file
+ if (name == null) {
+ throw new AtomException(
+ "ERROR: No 'Title' present in HTTP headers");
}
+ try {
+ FileManager fmgr = mRoller.getFileManager();
+ tempFile = File.createTempFile(name,"tmp");
+ FileOutputStream fos = new FileOutputStream(tempFile);
+ Utilities.copyInputToOutput(is, fos);
+ fos.close();
+
+ // If save is allowed by Roller system-wide policies
+ if (fmgr.canSave(website.getHandle(), name, contentType, tempFile.length(), msgs)) {
+ // Then save the file
+ FileInputStream fis = new FileInputStream(tempFile);
+ fmgr.saveFile(website.getHandle(), name, contentType, tempFile.length(), fis);
+ fis.close();
+
+ File resource = new File(fmgr.getUploadDir() + File.separator + name);
+ return createAtomResourceEntry(website, resource);
+ }
- } catch (Exception e) {
- String msg = "ERROR in atom.postResource";
- mLogger.error(msg,e);
- throw new Exception(msg);
- } finally {
- if (tempFile != null) tempFile.delete();
+ } catch (IOException e) {
+ String msg = "ERROR reading posted file";
+ mLogger.error(msg,e);
+ throw new AtomException(msg, e);
+ } finally {
+ if (tempFile != null) tempFile.delete();
+ }
}
+ // TODO: AtomUnsupportedMediaType and AtomRequestEntityTooLarge needed?
+ throw new AtomException("File upload denied because:" + msgs.toString());
+
+ } catch (RollerException re) {
+ throw new AtomException("ERROR: posting media");
}
- throw new Exception("File upload denied because:" + msgs.toString());
- }
-
- /**
- * Get absolute path to resource specified by path info.
- */
- public Entry getMedia(String[] pathInfo) throws Exception {
- String handle = pathInfo[0];
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- String uploadPath = RollerFactory.getRoller().getFileManager().getUploadUrl();
- File resource = new File(uploadPath + File.separator + pathInfo[2]);
- return createAtomResourceEntry(website, resource);
}
/**
* Update resource specified by pathInfo using data from input stream.
- * Expects pathInfo of form /blog-name/resources/name
+ * Expects pathInfo of form /blog-name/resource/name
*/
public Entry putMedia(String[] pathInfo,
- String contentType, InputStream is) throws Exception {
+ String contentType, InputStream is) throws AtomException {
if (pathInfo.length > 2) {
String name = pathInfo[2];
return postMedia(pathInfo, name, contentType, is);
}
- throw new Exception("ERROR: bad pathInfo");
- }
-
- /**
- * Delete resource specified by pathInfo.
- * Expects pathInfo of form /blog-name/resources/name
- */
- public void deleteMedia(String[] pathInfo) throws Exception {
- // authenticated client posted a weblog entry
- String handle = pathInfo[0];
- WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
- if (canEdit(website) && pathInfo.length > 1) {
- try {
- FileManager fmgr = mRoller.getFileManager();
- fmgr.deleteFile(website.getHandle(), pathInfo[2]);
- } catch (Exception e) {
- String msg = "ERROR in atom.deleteResource";
- mLogger.error(msg,e);
- throw new Exception(msg);
- }
- }
- else throw new Exception("ERROR not authorized to edit website");
+ throw new AtomException("ERROR: bad pathInfo");
}
-
+
//------------------------------------------------------------------ URI testers
/**
@@ -502,14 +659,15 @@
* True if URL is a entry URI.
*/
public boolean isEntryURI(String[] pathInfo) {
- if (pathInfo.length > 1 && pathInfo[1].equals("entry")) return true;
+ if (pathInfo.length > 2 && pathInfo[1].equals("entry")) return true;
+ if (pathInfo.length > 2 && pathInfo[1].equals("resource") && pathInfo[2].endsWith(".media-link")) return true;
return false;
}
-
+
/**
- * True if URL is a resource URI.
+ * True if URL is media edit URI. Media can be udpated, but not metadata.
*/
- public boolean isMediaURI(String[] pathInfo) {
+ public boolean isMediaEditURI(String[] pathInfo) {
if (pathInfo.length > 1 && pathInfo[1].equals("resource")) return true;
return false;
}
@@ -532,30 +690,6 @@
return false;
}
- /**
- * True if URL is a entry collection URI.
- */
- public boolean isEntryCollectionURI(String[] pathInfo) {
- if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
- return false;
- }
-
- /**
- * True if URL is a resource collection URI.
- */
- public boolean isMediaCollectionURI(String[] pathInfo) {
- if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
- return false;
- }
-
- /**
- * True if URL is a category collection URI.
- */
- public boolean isCategoryCollectionURI(String[] pathInfo) {
- if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
- return false;
- }
-
//------------------------------------------------------------------ permissions
/**
@@ -646,7 +780,7 @@
}
/**
- * Untested (and currently unused) implementation of BASIC authentication
+ * BASIC authentication.
*/
public String authenticateBASIC(HttpServletRequest request) {
boolean valid = false;
@@ -664,18 +798,18 @@
int p = userPass.indexOf(":");
if (p != -1) {
userID = userPass.substring(0, p);
- UserData user = mRoller.getUserManager().getUserByUserName(userID);
+ UserData user = mRoller.getUserManager().getUserByUserName(userID);
boolean enabled = user.getEnabled().booleanValue();
- if (enabled) {
+ if (enabled) {
// are passwords encrypted?
- RollerContext rollerContext =
- RollerContext.getRollerContext();
- String encrypted =
- RollerConfig.getProperty("passwds.encryption.enabled");
+ RollerContext rollerContext =
+ RollerContext.getRollerContext();
+ String encrypted =
+ RollerConfig.getProperty("passwds.encryption.enabled");
password = userPass.substring(p+1);
if ("true".equalsIgnoreCase(encrypted)) {
- password = Utilities.encodePassword(password,
- RollerConfig.getProperty("passwds.encryption.algorithm"));
+ password = Utilities.encodePassword(password,
+ RollerConfig.getProperty("passwds.encryption.algorithm"));
}
valid = user.getPassword().equals(password);
}
@@ -710,12 +844,12 @@
atomEntry.setTitle( entry.getTitle());
atomEntry.setContents( contents);
atomEntry.setPublished( entry.getPubTime());
- atomEntry.setUpdated( entry.getUpdateTime());
-
- UserData creator = entry.getCreator();
+ atomEntry.setUpdated( entry.getUpdateTime());
+
+ UserData creator = entry.getCreator();
Person author = new Person();
- author.setName( creator.getUserName());
- author.setEmail( creator.getEmailAddress());
+ author.setName( creator.getUserName());
+ author.setEmail( creator.getEmailAddress());
atomEntry.setAuthors( Collections.singletonList(author));
List categories = new ArrayList();
@@ -733,8 +867,9 @@
Link editlink = new Link();
editlink.setRel("edit");
- editlink.setHref(absUrl + "/app/"
- + entry.getWebsite().getHandle() + "/entry/" + entry.getId());
+ editlink.setHref(
+ URLUtilities.getAtomProtocolURL(true)
+ +"/"+entry.getWebsite().getHandle() + "/entry/" + entry.getId());
List otherlinks = new ArrayList();
otherlinks.add(editlink);
atomEntry.setOtherLinks(otherlinks);
@@ -742,35 +877,50 @@
List modules = new ArrayList();
PubControlModule pubControl = new PubControlModuleImpl();
pubControl.setDraft(
- !WeblogEntryData.PUBLISHED.equals(entry.getStatus()));
+ !WeblogEntryData.PUBLISHED.equals(entry.getStatus()));
modules.add(pubControl);
atomEntry.setModules(modules);
return atomEntry;
}
- private Entry createAtomResourceEntry(WebsiteData website, File file) {
+ private Entry createAtomResourceEntry(WebsiteData website, File file) {
String absUrl = RollerRuntimeConfig.getAbsoluteContextURL();
- String editURI = absUrl
- + "/app/" + website.getHandle()
+ String editURI =
+ URLUtilities.getAtomProtocolURL(true)+"/"+website.getHandle()
+ + "/resource/" + file.getName() + ".media-link";
+ String editMediaURI =
+ URLUtilities.getAtomProtocolURL(true)+"/"+ website.getHandle()
+ "/resource/" + file.getName();
String viewURI = absUrl
+ "/resources/" + website.getHandle()
+ "/" + file.getName();
+
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);
-
+
Entry entry = new Entry();
+ entry.setId(editMediaURI);
entry.setTitle(file.getName());
entry.setUpdated(new Date(file.lastModified()));
-
- Link editlink = new Link();
- editlink.setRel("edit");
- editlink.setHref(editURI);
- List otherlinks = new ArrayList();
- otherlinks.add(editlink);
+
+ 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);
@@ -805,9 +955,9 @@
rollerEntry.setPubTime(pubTime);
rollerEntry.setUpdateTime(updateTime);
rollerEntry.setWebsite(website);
-
- PubControlModule control =
- (PubControlModule)entry.getModule("http://purl.org/atom/app#");
+
+ PubControlModule control =
+ (PubControlModule)entry.getModule("http://purl.org/atom/app#");
if (control!=null && control.getDraft()) {
rollerEntry.setStatus(WeblogEntryData.DRAFT);
} else {
@@ -824,8 +974,8 @@
String catString = cat.getTerm() != null ? cat.getTerm() : cat.getLabel();
if (catString != null) {
WeblogCategoryData rollerCat =
- mRoller.getWeblogManager().getWeblogCategoryByPath(
- website, catString);
+ mRoller.getWeblogManager().getWeblogCategoryByPath(
+ website, catString);
if (rollerCat != null) {
// Found a valid category, so break out
rollerEntry.setCategory(rollerCat);
@@ -833,10 +983,12 @@
}
}
}
- } else {
- // or we fall back to the default Blogger API category
+ }
+ if (rollerEntry.getCategory() == null) {
+ // no category? fall back to the default Blogger API category
rollerEntry.setCategory(website.getBloggerCategory());
}
return rollerEntry;
}
+
}
Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/webservices/xmlrpc/MetaWeblogAPIHandler.java Sun Aug 6 08:43:26 2006
@@ -359,10 +359,9 @@
RollerMessages msgs = new RollerMessages();
// If save is allowed by Roller system-wide policies
- if (fmgr.canSave(website.getHandle(), name, bits.length, msgs)) {
+ if (fmgr.canSave(website.getHandle(), name, type, bits.length, msgs)) {
// Then save the file
- fmgr.saveFile(
- website.getHandle(), name, bits.length, new ByteArrayInputStream(bits));
+ fmgr.saveFile(website.getHandle(), name, type, bits.length, new ByteArrayInputStream(bits));
RollerRequest rreq = RollerRequest.getRollerRequest();
HttpServletRequest request = rreq.getRequest();
Modified: incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/PlanetManagerLocalTest.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/PlanetManagerLocalTest.java?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/PlanetManagerLocalTest.java (original)
+++ incubator/roller/branches/roller_3.0/tests/org/apache/roller/business/PlanetManagerLocalTest.java Sun Aug 6 08:43:26 2006
@@ -18,16 +18,13 @@
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
-
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.TestUtils;
-
import org.apache.roller.model.PlanetManager;
import org.apache.roller.model.RollerFactory;
import org.apache.roller.pojos.UserData;
@@ -35,6 +32,8 @@
import org.apache.roller.pojos.WebsiteData;
import org.apache.roller.ui.core.tasks.RefreshEntriesTask;
import org.apache.roller.ui.core.tasks.SyncWebsitesTask;
+
+
/**
* Test database implementation of PlanetManager for local feeds.
Modified: incubator/roller/branches/roller_3.0/tools/lib/rome-0.8.jar
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/tools/lib/rome-0.8.jar?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
Binary files - no diff available.
Modified: incubator/roller/branches/roller_3.0/tools/lib/rome-fetcher-0.8.jar
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/tools/lib/rome-fetcher-0.8.jar?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
Binary files - no diff available.
Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/classes/ApplicationResources.properties
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/classes/ApplicationResources.properties?rev=429139&r1=429138&r2=429139&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/classes/ApplicationResources.properties (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/classes/ApplicationResources.properties Sun Aug 6 08:43:26 2006
@@ -420,7 +420,7 @@
error.upload.disabled=File Upload has been turned off
error.upload.file=No file selected
error.upload.filemax=File larger than maximum allowed: {0} MB
-error.upload.forbiddenFile=You can only upload files ending in {0}
+error.upload.forbiddenFile=You can only upload files with these extensions and content-types: {0}
error.general=ERROR: Unexpected Exception [{0}] has been logged.