1 18 package org.apache.roller.webservices.atomprotocol; 19 20 import java.io.IOException ; 21 import java.io.InputStreamReader ; 22 import java.io.Reader ; 23 import java.io.Writer ; 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 28 import javax.servlet.ServletException ; 29 import javax.servlet.http.HttpServlet ; 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 33 import org.apache.commons.lang.StringUtils; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.jdom.Document; 37 import org.jdom.Element; 38 import org.jdom.JDOMException; 39 import org.jdom.input.SAXBuilder; 40 import org.jdom.output.Format; 41 import org.jdom.output.XMLOutputter; 42 43 import com.sun.syndication.feed.atom.Entry; 44 import com.sun.syndication.feed.atom.Feed; 45 import com.sun.syndication.feed.atom.Link; 46 import com.sun.syndication.io.FeedException; 47 import com.sun.syndication.io.WireFeedInput; 48 import com.sun.syndication.io.WireFeedOutput; 49 import java.io.BufferedReader ; 50 import java.io.StringWriter ; 51 import org.jdom.Namespace; 52 import org.apache.roller.config.RollerConfig; 53 54 60 public class AtomServlet extends HttpServlet { 61 public static final String FEED_TYPE = "atom_1.0"; 62 63 private static Log mLogger = 64 LogFactory.getFactory().getInstance(AtomServlet.class); 65 66 71 private AtomHandler createAtomRequestHandler(HttpServletRequest request) 72 throws ServletException { 73 boolean enabled = RollerConfig.getBooleanProperty( 74 "webservices.atomprotocol.enabled"); 75 if (!enabled) { 76 throw new ServletException ("ERROR: Atom protocol not enabled"); 77 } 78 return new RollerAtomHandler(request); 79 } 80 81 85 protected void doGet(HttpServletRequest req, HttpServletResponse res) 86 throws ServletException , IOException { 87 AtomHandler handler = createAtomRequestHandler(req); 88 String userName = handler.getAuthenticatedUsername(); 89 if (userName != null) { 90 String [] pathInfo = getPathInfo(req); 91 try { 92 if (handler.isIntrospectionURI(pathInfo)) { 93 AtomService service = handler.getIntrospection(); 95 Document doc = AtomService.serviceToDocument(service); 96 res.setContentType("application/atomserv+xml; charset=utf-8"); 97 Writer writer = res.getWriter(); 98 XMLOutputter outputter = new XMLOutputter(); 99 outputter.setFormat(Format.getPrettyFormat()); 100 outputter.output(doc, writer); 101 writer.close(); 102 res.setStatus(HttpServletResponse.SC_OK); 103 } 104 else if (handler.isCollectionURI(pathInfo)) { 105 Feed col = handler.getCollection(pathInfo); 107 col.setFeedType(FEED_TYPE); 108 WireFeedOutput wireFeedOutput = new WireFeedOutput(); 109 Document feedDoc = wireFeedOutput.outputJDom(col); 110 res.setContentType("application/atom+xml; charset=utf-8"); 111 Writer writer = res.getWriter(); 112 XMLOutputter outputter = new XMLOutputter(); 113 outputter.setFormat(Format.getPrettyFormat()); 114 outputter.output(feedDoc, writer); 115 writer.close(); 116 res.setStatus(HttpServletResponse.SC_OK); 117 } 118 else if (handler.isEntryURI(pathInfo)) { 119 Entry entry = handler.getEntry(pathInfo); 121 if (entry != null) { 122 res.setContentType("application/atom+xml; charset=utf-8"); 123 Writer writer = res.getWriter(); 124 serializeEntry(entry, writer); 125 writer.close(); 126 } else { 127 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 128 } 129 } else { 130 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 131 } 132 } catch (AtomException ae) { 133 res.setStatus(ae.getStatus()); 134 mLogger.debug(ae); 135 } catch (Exception ae) { 136 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 137 mLogger.debug(ae); 138 } 139 } else { 140 res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\""); 141 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 142 } 143 } 144 145 150 protected void doPost(HttpServletRequest req, HttpServletResponse res) 151 throws ServletException , IOException { 152 AtomHandler handler = createAtomRequestHandler(req); 153 String userName = handler.getAuthenticatedUsername(); 154 if (userName != null) { 155 String [] pathInfo = getPathInfo(req); 156 try { 157 if (handler.isCollectionURI(pathInfo)) { 158 159 if (req.getContentType().startsWith("application/atom+xml")) { 160 161 Entry unsavedEntry = parseEntry(new BufferedReader ( 163 new InputStreamReader ( 164 req.getInputStream(), "UTF-8"))); 165 166 Entry savedEntry = handler.postEntry(pathInfo, unsavedEntry); 168 169 Iterator links = savedEntry.getOtherLinks().iterator(); 171 while (links.hasNext()) { 172 Link link = (Link) links.next(); 173 if (link.getRel().equals("edit") || link.getRel() == null) { 174 res.addHeader("Location", link.getHref()); 175 break; 176 } 177 } 178 res.setStatus(HttpServletResponse.SC_CREATED); 180 res.setContentType("application/atom+xml; charset=utf-8"); 181 Writer writer = res.getWriter(); 182 serializeEntry(savedEntry, writer); 183 writer.close(); 184 185 } else if (req.getContentType() != null) { 186 String title = req.getHeader("Title"); 188 String slug = req.getHeader("Slug"); 189 190 Entry resource = handler.postMedia( 192 pathInfo, title, slug, req.getContentType(), req.getInputStream()); 193 194 res.setStatus(HttpServletResponse.SC_CREATED); 195 com.sun.syndication.feed.atom.Content content = 196 (com.sun.syndication.feed.atom.Content)resource.getContents().get(0); 197 198 Iterator links = resource.getOtherLinks().iterator(); 200 while (links.hasNext()) { 201 Link link = (Link) links.next(); 202 if (link.getRel().equals("edit") || link.getRel() == null) { 203 res.addHeader("Location", link.getHref()); 204 break; 205 } 206 } 207 Writer writer = res.getWriter(); 208 serializeEntry(resource, writer); 209 writer.close(); 210 } else { 211 res.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); 212 } 213 214 } else { 215 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 216 } 217 } catch (AtomException ae) { 218 res.setStatus(ae.getStatus()); 219 mLogger.debug(ae); 220 } catch (Exception ae) { 221 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 222 mLogger.debug(ae); 223 } 224 } else { 225 res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\""); 226 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 227 } 228 } 229 230 235 protected void doPut(HttpServletRequest req, HttpServletResponse res) 236 throws ServletException , IOException { 237 AtomHandler handler = createAtomRequestHandler(req); 238 String userName = handler.getAuthenticatedUsername(); 239 if (userName != null) { 240 String [] pathInfo = getPathInfo(req); 241 try { 242 if (handler.isEntryURI(pathInfo)) { 243 244 Entry unsavedEntry = parseEntry(new BufferedReader ( 246 new InputStreamReader ( 247 req.getInputStream(), "UTF-8"))); 248 249 Entry updatedEntry = handler.putEntry(pathInfo, unsavedEntry); 251 252 res.setContentType("application/atom+xml; charset=utf-8"); 254 Writer writer = res.getWriter(); 255 serializeEntry(updatedEntry, writer); 256 res.setStatus(HttpServletResponse.SC_OK); 257 writer.close(); 258 259 } else if (handler.isMediaEditURI(pathInfo)) { 260 261 Entry updatedEntry = handler.putMedia( 263 pathInfo, req.getContentType(), req.getInputStream()); 264 265 res.setContentType("application/atom+xml; charset=utf-8"); 267 Writer writer = res.getWriter(); 268 serializeEntry(updatedEntry, writer); 269 writer.close(); 270 res.setStatus(HttpServletResponse.SC_OK); 271 272 } else { 273 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 274 } 275 } catch (AtomException ae) { 276 res.setStatus(ae.getStatus()); 277 mLogger.debug(ae); 278 } catch (Exception ae) { 279 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 280 mLogger.debug(ae); 281 } 282 } else { 283 res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\""); 284 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 285 } 286 } 287 288 292 protected void doDelete(HttpServletRequest req, HttpServletResponse res) 293 throws ServletException , IOException { 294 AtomHandler handler = createAtomRequestHandler(req); 295 String userName = handler.getAuthenticatedUsername(); 296 if (userName != null) { 297 String [] pathInfo = getPathInfo(req); 298 try { 299 if (handler.isEntryURI(pathInfo)) { 300 handler.deleteEntry(pathInfo); 301 res.setStatus(HttpServletResponse.SC_OK); 302 } 303 else { 304 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 305 } 306 } catch (AtomException ae) { 307 res.setStatus(ae.getStatus()); 308 mLogger.debug(ae); 309 } catch (Exception ae) { 310 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 311 mLogger.debug(ae); 312 } 313 } else { 314 res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\""); 315 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 316 } 317 } 318 319 323 protected String [] getPathInfo(HttpServletRequest request) { 324 String mPathInfo = request.getPathInfo(); 325 mPathInfo = (mPathInfo!=null) ? mPathInfo : ""; 326 return StringUtils.split(mPathInfo,"/"); 327 } 328 329 332 public static void serializeEntry(Entry entry, Writer writer) 333 throws IllegalArgumentException , FeedException, IOException { 334 List entries = new ArrayList (); 336 entries.add(entry); 337 Feed feed1 = new Feed(); 338 feed1.setFeedType(AtomServlet.FEED_TYPE); 339 feed1.setEntries(entries); 340 341 WireFeedOutput wireFeedOutput = new WireFeedOutput(); 343 Document feedDoc = wireFeedOutput.outputJDom(feed1); 344 345 Element entryElement= (Element)feedDoc.getRootElement().getChildren().get(0); 347 348 Element rollerElement = new Element("atom-draft", 351 "http://rollerweblogger.org/namespaces/app"); 352 rollerElement.setText("9"); 353 entryElement.addContent(rollerElement); 354 355 XMLOutputter outputter = new XMLOutputter(); 356 outputter.setFormat(Format.getPrettyFormat()); 357 358 if (mLogger.isDebugEnabled()) { 359 StringWriter sw = new StringWriter (); 360 outputter.output(entryElement, sw); 361 mLogger.debug(sw.toString()); 362 writer.write(sw.toString()); 363 } else { 364 outputter.output(entryElement, writer); 365 } 366 } 367 368 371 public static Entry parseEntry(Reader rd) 372 throws JDOMException, IOException , IllegalArgumentException , FeedException { 373 SAXBuilder builder = new SAXBuilder(); 375 Document entryDoc = builder.build(rd); 376 Element fetchedEntryElement = entryDoc.getRootElement(); 377 fetchedEntryElement.detach(); 378 379 Feed feed = new Feed(); 381 feed.setFeedType(FEED_TYPE); 382 WireFeedOutput wireFeedOutput = new WireFeedOutput(); 383 Document feedDoc = wireFeedOutput.outputJDom(feed); 384 feedDoc.getRootElement().addContent(fetchedEntryElement); 385 386 Namespace ns = Namespace.getNamespace( 389 "http://rollerweblogger.org/namespaces/app"); 390 Element rollerElement = fetchedEntryElement.getChild("atom-draft", ns); 391 if (rollerElement == null) { 392 mLogger.debug("Client is NOT preserving foreign markup"); 393 } 394 395 WireFeedInput input = new WireFeedInput(); 396 Feed parsedFeed = (Feed)input.build(feedDoc); 397 return (Entry)parsedFeed.getEntries().get(0); 398 } 399 } 400 | Popular Tags |