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/05/02 00:23:34 UTC
svn commit: r398712 [26/32] - in /incubator/roller/trunk/src/org/apache: ./
roller/ roller/business/ roller/business/hibernate/
roller/business/referrers/ roller/business/runnable/
roller/business/search/ roller/business/search/operations/ roller/busin...
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomService.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomService.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomService.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomService.java Mon May 1 15:23:02 2006
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.filter.Filter;
+
+/**
+ * This class models an Atom workspace.
+ * @author Dave Johnson
+ */
+/* Based on: draft-ietf-atompub-protocol-08.txt
+ *
+ * appService =
+ * element app:service {
+ * appCommonAttributes,
+ * ( appWorkspace+
+ * & extensionElement* )
+ * }
+ *
+ * Here is an example Atom workspace:
+ *
+ * <?xml version="1.0" encoding='utf-8'?>
+ * <service xmlns="http://purl.org/atom/app#">
+ * <workspace title="Main Site" >
+ * <collection
+ * title="My Blog Entries"
+ * href="http://example.org/reilly/main" >
+ * <member-type>entry</member-type>
+ * </collection>
+ * <collection
+ * title="Pictures"
+ * href="http://example.org/reilly/pic" >
+ * <member-type>media</member-type>
+ * </collection>
+ * </workspace>
+ * </service>
+ */
+public class AtomService {
+ public static final Namespace ns =
+ Namespace.getNamespace("http://purl.org/atom/app#");
+
+ private List workspaces = new ArrayList();
+
+ public AtomService() {
+ }
+
+ public void addWorkspace(AtomService.Workspace workspace) {
+ workspaces.add(workspace);
+ }
+
+ public List getWorkspaces() {
+ return workspaces;
+ }
+
+ public void setWorkspaces(List workspaces) {
+ this.workspaces = workspaces;
+ }
+
+ /**
+ * This class models an Atom workspace.
+ *
+ * @author Dave Johnson
+ */
+ /*
+ * appWorkspace = element app:workspace { attribute title { text }, (
+ * appCollection* & anyElement* ) }
+ */
+ public static class Workspace {
+ private String title = null;
+ private List collections = new ArrayList();
+
+ public Workspace() {
+ }
+
+ public List getCollections() {
+ return collections;
+ }
+
+ public void setCollections(List collections) {
+ this.collections = collections;
+ }
+
+ public void addCollection(AtomService.Collection col) {
+ collections.add(col);
+ }
+
+ /** Workspace must have a human readable title */
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+ }
+
+ /**
+ * This class models an Atom workspace collection.
+ * @author Dave Johnson
+ */
+ /* appCollection =
+ * element app:collection {
+ * appCommonAttributes,
+ * attribute title { text },
+ * attribute href { text },
+ * ( appMemberType
+ * & appListTemplate
+ * & extensionElement* )
+ * }
+ */
+ public static class Collection {
+ private String title = null;
+ private String memberType = "entry"; // or "media"
+ private String listTemplate = null;
+ private String href = null;
+
+ public Collection() {
+ }
+
+ /**
+ * Member type May be "entry" or "media".
+ */
+ public String getMemberType() {
+ return memberType;
+ }
+
+ public void setMemberType(String memberType) {
+ this.memberType = memberType;
+ }
+
+ /** The URI of the collection */
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+
+ /** Must have human readable title */
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+ }
+
+ /** Deserialize an Atom service XML document into an object */
+ public static AtomService documentToService(Document document) {
+ AtomService service = new AtomService();
+ Element root = document.getRootElement();
+ List spaces = root.getChildren("workspace", ns);
+ Iterator iter = spaces.iterator();
+ while (iter.hasNext()) {
+ Element e = (Element) iter.next();
+ service.addWorkspace(AtomService.elementToWorkspace(e));
+ }
+ return service;
+ }
+
+ /** Serialize an AtomService object into an XML document */
+ public static Document serviceToDocument(AtomService service) {
+ Document doc = new Document();
+ Element root = new Element("service", ns);
+ doc.setRootElement(root);
+ Iterator iter = service.getWorkspaces().iterator();
+ while (iter.hasNext()) {
+ AtomService.Workspace space = (AtomService.Workspace) iter.next();
+ root.addContent(AtomService.workspaceToElement(space));
+ }
+ return doc;
+ }
+
+ /** Deserialize a Atom workspace XML element into an object */
+ public static AtomService.Workspace elementToWorkspace(Element element) {
+ AtomService.Workspace space = new AtomService.Workspace();
+ space.setTitle(element.getAttribute("title").getValue());
+ List collections = element.getChildren("collection", ns);
+ Iterator iter = collections.iterator();
+ while (iter.hasNext()) {
+ Element e = (Element) iter.next();
+ space.addCollection(AtomService.elementToCollection(e));
+ }
+ return space;
+ }
+
+ /** Serialize an AtomService.Workspace object into an XML element */
+ public static Element workspaceToElement(Workspace space) {
+ Namespace ns = Namespace.getNamespace("http://purl.org/atom/app#");
+ Element element = new Element("workspace", ns);
+ element.setAttribute("title", space.getTitle());
+ Iterator iter = space.getCollections().iterator();
+ while (iter.hasNext()) {
+ AtomService.Collection col = (AtomService.Collection) iter.next();
+ element.addContent(collectionToElement(col));
+ }
+ return element;
+ }
+
+ /** Deserialize an Atom service collection XML element into an object */
+ public static AtomService.Collection elementToCollection(Element element) {
+ AtomService.Collection collection = new AtomService.Collection();
+ collection.setTitle(element.getAttribute("title").getValue());
+ collection.setHref(element.getAttribute("href").getValue());
+ Element memberType = element.getChild("member-type", ns);
+ if (memberType != null) {
+ collection.setMemberType(memberType.getText());
+ }
+ return collection;
+ }
+
+ /** Serialize an AtomService.Collection object into an XML element */
+ public static Element collectionToElement(AtomService.Collection collection) {
+ Namespace ns = Namespace.getNamespace("http://purl.org/atom/app#");
+ Element element = new Element("collection", ns);
+ element.setAttribute("title", collection.getTitle());
+ element.setAttribute("href", collection.getHref());
+
+ Element memberType = new Element("member-type", ns);
+ memberType.setText(collection.getMemberType());
+ element.addContent(memberType);
+
+ return element;
+ }
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomServlet.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomServlet.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomServlet.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/AtomServlet.java Mon May 1 15:23:02 2006
@@ -0,0 +1,375 @@
+/*
+ * 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.
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
+
+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.io.FeedException;
+import com.sun.syndication.io.WireFeedInput;
+import com.sun.syndication.io.WireFeedOutput;
+import java.io.StringWriter;
+import org.jdom.Namespace;
+import org.apache.roller.config.RollerConfig;
+
+/**
+ * Atom Servlet implements Atom by calling a Roller independent handler.
+ * @web.servlet name="AtomServlet"
+ * @web.servlet-mapping url-pattern="/app/*"
+ * @author David M Johnson
+ */
+public class AtomServlet extends HttpServlet {
+ public static final String FEED_TYPE = "atom_1.0";
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(AtomServlet.class);
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Create an Atom request handler.
+ * TODO: make AtomRequestHandler implementation configurable.
+ */
+ private AtomHandler createAtomRequestHandler(HttpServletRequest request)
+ throws ServletException {
+ boolean enabled = RollerConfig.getBooleanProperty(
+ "webservices.atomprotocol.enabled");
+ if (!enabled) {
+ throw new ServletException("ERROR: Atom protocol not enabled");
+ }
+ return new RollerAtomHandler(request);
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Handles an Atom GET by calling handler and writing results to response.
+ */
+ protected void doGet(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ AtomHandler handler = createAtomRequestHandler(req);
+ String userName = handler.getAuthenticatedUsername();
+ if (userName != null) {
+ String[] pathInfo = getPathInfo(req);
+ try {
+ if (handler.isIntrospectionURI(pathInfo)) {
+ // return an Atom Service document
+ AtomService service = handler.getIntrospection(pathInfo);
+ Document doc = AtomService.serviceToDocument(service);
+ res.setContentType("application/xml; charset=utf8");
+ Writer writer = res.getWriter();
+ XMLOutputter outputter = new XMLOutputter();
+ outputter.setFormat(Format.getPrettyFormat());
+ outputter.output(doc, writer);
+ writer.close();
+ res.setStatus(HttpServletResponse.SC_OK);
+ } else if (handler.isCollectionURI(pathInfo)) {
+ // return a collection
+ Feed col = handler.getCollection(pathInfo);
+ col.setFeedType(FEED_TYPE);
+ WireFeedOutput wireFeedOutput = new WireFeedOutput();
+ Document feedDoc = wireFeedOutput.outputJDom(col);
+ res.setContentType("application/atom+xml; charset=utf8");
+ Writer writer = res.getWriter();
+ XMLOutputter outputter = new XMLOutputter();
+ outputter.setFormat(Format.getPrettyFormat());
+ outputter.output(feedDoc, writer);
+ writer.close();
+ res.setStatus(HttpServletResponse.SC_OK);
+ } else if (handler.isEntryURI(pathInfo)) {
+ // return an entry
+ Entry entry = handler.getEntry(pathInfo);
+ if (entry != null) {
+ Writer writer = res.getWriter();
+ res.setContentType("application/atom+xml; charset=utf8");
+ serializeEntry(entry, writer);
+ writer.close();
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } else if (handler.isMediaURI(pathInfo)) {
+ // return a resource entry
+ Entry entry = handler.getMedia(pathInfo);
+ if (entry != null) {
+ Writer writer = res.getWriter();
+ res.setContentType("application/atom+xml; charset=utf8");
+ serializeEntry(entry, writer);
+ writer.close();
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } catch (Throwable e) {
+ res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ e.printStackTrace(res.getWriter());
+ mLogger.error(e);
+ }
+ } else {
+ res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\"");
+ res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Handles an Atom POST by calling handler to identify URI, reading/parsing
+ * data, calling handler and writing results to response.
+ */
+ protected void doPost(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ AtomHandler handler = createAtomRequestHandler(req);
+ String userName = handler.getAuthenticatedUsername();
+ if (userName != null) {
+ String[] pathInfo = getPathInfo(req);
+ try {
+ if (handler.isEntryCollectionURI(pathInfo)) {
+
+ // parse incoming entry
+ Entry unsavedEntry = parseEntry(
+ new InputStreamReader(req.getInputStream()));
+
+ // call handler to post it
+ Entry savedEntry = handler.postEntry(pathInfo, unsavedEntry);
+ Iterator links = savedEntry.getAlternateLinks().iterator();
+
+ // return alternate link as Location header
+ while (links.hasNext()) {
+ Link link = (Link) links.next();
+ if (link.getRel().equals("alternate") || link.getRel() == null) {
+ res.addHeader("Location", link.getHref());
+ break;
+ }
+ }
+ // write entry back out to response
+ res.setStatus(HttpServletResponse.SC_CREATED);
+ res.setContentType("application/atom+xml; charset=utf8");
+ Writer writer = res.getWriter();
+ serializeEntry(savedEntry, writer);
+ writer.close();
+ } else if (handler.isMediaCollectionURI(pathInfo)) {
+ // get incoming file name from HTTP header
+ String name = req.getHeader("Title");
+
+ // hand input stream of to hander to post file
+ Entry resource = handler.postMedia(
+ pathInfo, name, req.getContentType(), req.getInputStream());
+ res.setStatus(HttpServletResponse.SC_CREATED);
+ com.sun.syndication.feed.atom.Content content =
+ (com.sun.syndication.feed.atom.Content)resource.getContents().get(0);
+ res.setHeader("Location", content.getSrc());
+ Writer writer = res.getWriter();
+ serializeEntry(resource, writer);
+ writer.close();
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } catch (Throwable e) {
+ res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ e.printStackTrace(res.getWriter());
+ mLogger.error(e);
+ }
+ } else {
+ res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\"");
+ res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Handles an Atom PUT by calling handler to identify URI, reading/parsing
+ * data, calling handler and writing results to response.
+ */
+ protected void doPut(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ AtomHandler handler = createAtomRequestHandler(req);
+ String userName = handler.getAuthenticatedUsername();
+ if (userName != null) {
+ String[] pathInfo = getPathInfo(req);
+ try {
+ if (handler.isEntryURI(pathInfo)) {
+ // parse incoming entry
+ Entry unsavedEntry = parseEntry(
+ new InputStreamReader(req.getInputStream()));
+
+ // call handler to put entry
+ Entry updatedEntry = handler.putEntry(pathInfo, unsavedEntry);
+
+ // write entry back out to response
+ res.setContentType("application/atom+xml; charset=utf8");
+ Writer writer = res.getWriter();
+ serializeEntry(updatedEntry, writer);
+ res.setStatus(HttpServletResponse.SC_OK);
+ writer.close();
+ } else if (handler.isMediaURI(pathInfo)) {
+ // hand input stream to handler
+ Entry updatedEntry = handler.putMedia(
+ pathInfo, req.getContentType(), req.getInputStream());
+
+ // write entry back out to response
+ res.setContentType("application/atom+xml; charset=utf8");
+ Writer writer = res.getWriter();
+ serializeEntry(updatedEntry, writer);
+ writer.close();
+ res.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } catch (Throwable e) {
+ res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ e.printStackTrace(res.getWriter());
+ mLogger.error(e);
+ }
+ } else {
+ res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\"");
+ res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Handle Atom DELETE by calling appropriate handler.
+ */
+ protected void doDelete(HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException {
+ AtomHandler handler = createAtomRequestHandler(req);
+ String userName = handler.getAuthenticatedUsername();
+ if (userName != null) {
+ String[] pathInfo = getPathInfo(req);
+ try {
+ if (handler.isEntryURI(pathInfo)) {
+ handler.deleteEntry(pathInfo);
+ res.setStatus(HttpServletResponse.SC_OK);
+ } else if (handler.isMediaURI(pathInfo)) {
+ handler.deleteMedia(pathInfo);
+ res.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } catch (Throwable e) {
+ res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ e.printStackTrace(res.getWriter());
+ mLogger.error(e);
+ }
+ } else {
+ res.setHeader("WWW-Authenticate", "BASIC realm=\"Roller\"");
+ res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ }
+ }
+
+ //-----------------------------------------------------------------------------
+ /**
+ * Convenience method to return the PathInfo from the request.
+ */
+ protected String[] getPathInfo(HttpServletRequest request) {
+ String mPathInfo = request.getPathInfo();
+ mPathInfo = (mPathInfo!=null) ? mPathInfo : "";
+ return StringUtils.split(mPathInfo,"/");
+ }
+
+ /**
+ * Serialize entry to writer.
+ */
+ public static void serializeEntry(Entry entry, Writer writer)
+ throws IllegalArgumentException, FeedException, IOException {
+ // Build a feed containing only the entry
+ List entries = new ArrayList();
+ entries.add(entry);
+ Feed feed1 = new Feed();
+ feed1.setFeedType(AtomServlet.FEED_TYPE);
+ feed1.setEntries(entries);
+
+ // Get Rome to output feed as a JDOM document
+ WireFeedOutput wireFeedOutput = new WireFeedOutput();
+ Document feedDoc = wireFeedOutput.outputJDom(feed1);
+
+ // Grab entry element from feed and get JDOM to serialize it
+ Element entryElement= (Element)feedDoc.getRootElement().getChildren().get(0);
+
+ // Add our own namespaced element, so we can determine if we can
+ // count on client to preserve foreign markup as it should.
+ Element rollerElement = new Element("atom-draft",
+ "http://rollerweblogger.org/namespaces/app");
+ rollerElement.setText("8");
+ entryElement.addContent(rollerElement);
+
+ XMLOutputter outputter = new XMLOutputter();
+ outputter.setFormat(Format.getPrettyFormat());
+
+ if (mLogger.isDebugEnabled()) {
+ StringWriter sw = new StringWriter();
+ outputter.output(entryElement, sw);
+ mLogger.debug(sw.toString());
+ writer.write(sw.toString());
+ } else {
+ outputter.output(entryElement, writer);
+ }
+ }
+
+ /**
+ * Parse entry from reader.
+ */
+ public static Entry parseEntry(Reader rd)
+ throws JDOMException, IOException, IllegalArgumentException, FeedException {
+ // Parse entry into JDOM tree
+ SAXBuilder builder = new SAXBuilder();
+ Document entryDoc = builder.build(rd);
+ Element fetchedEntryElement = entryDoc.getRootElement();
+ fetchedEntryElement.detach();
+
+ // Put entry into a JDOM document with 'feed' root so that Rome can handle it
+ Feed feed = new Feed();
+ feed.setFeedType(FEED_TYPE);
+ WireFeedOutput wireFeedOutput = new WireFeedOutput();
+ Document feedDoc = wireFeedOutput.outputJDom(feed);
+ feedDoc.getRootElement().addContent(fetchedEntryElement);
+
+ // Check for our special namespaced element. If it's there, then we
+ // know that client is not preserving foreign markup.
+ Namespace ns = Namespace.getNamespace(
+ "http://rollerweblogger.org/namespaces/app");
+ Element rollerElement = fetchedEntryElement.getChild("atom-draft", ns);
+ if (rollerElement == null) {
+ mLogger.debug("Client is NOT preserving foreign markup");
+ }
+
+ WireFeedInput input = new WireFeedInput();
+ Feed parsedFeed = (Feed)input.build(feedDoc);
+ return (Entry)parsedFeed.getEntries().get(0);
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModule.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModule.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModule.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModule.java Mon May 1 15:23:02 2006
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import com.sun.syndication.feed.module.Module;
+
+public interface PubControlModule extends Module {
+ public static final String URI = "http://purl.org/atom/app#";
+ public boolean getDraft();
+ public void setDraft(boolean draft);
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleGenerator.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleGenerator.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleGenerator.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleGenerator.java Mon May 1 15:23:02 2006
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleGenerator;
+
+public class PubControlModuleGenerator implements ModuleGenerator {
+ private static final Namespace PUBCONTROL_NS =
+ Namespace.getNamespace("app", PubControlModule.URI);
+
+ public String getNamespaceUri() {
+ return PubControlModule.URI;
+ }
+
+ private static final Set NAMESPACES;
+
+ static {
+ Set nss = new HashSet();
+ nss.add(PUBCONTROL_NS);
+ NAMESPACES = Collections.unmodifiableSet(nss);
+ }
+
+ public Set getNamespaces() {
+ return NAMESPACES;
+ }
+
+ public void generate(Module module, Element element) {
+ PubControlModule m = (PubControlModule)module;
+ String draft = m.getDraft() ? "yes" : "no";
+ Element control = new Element("control", PUBCONTROL_NS);
+ control.addContent(generateSimpleElement("draft", draft));
+ element.addContent(control);
+ }
+
+ protected Element generateSimpleElement(String name, String value) {
+ Element element = new Element(name, PUBCONTROL_NS);
+ element.addContent(value);
+ return element;
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import com.sun.syndication.feed.module.ModuleImpl;
+
+public class PubControlModuleImpl extends ModuleImpl implements PubControlModule {
+ private boolean _draft = false;
+
+ public PubControlModuleImpl() {
+ super(PubControlModule.class,PubControlModule.URI);
+ }
+ public boolean getDraft() {
+ return _draft;
+ }
+ public void setDraft(boolean draft) {
+ _draft = draft;
+ }
+ public Class getInterface() {
+ return PubControlModule.class;
+ }
+ public void copyFrom(Object obj) {
+ PubControlModule m = (PubControlModule)obj;
+ setDraft(m.getDraft());
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleParser.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleParser.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleParser.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/PubControlModuleParser.java Mon May 1 15:23:02 2006
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.
+ *
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+import com.sun.syndication.feed.module.Module;
+import com.sun.syndication.io.ModuleParser;
+
+public class PubControlModuleParser implements ModuleParser {
+
+ public String getNamespaceUri() {
+ return PubControlModule.URI;
+ }
+
+ public Namespace getContentNamespace() {
+ return Namespace.getNamespace(PubControlModule.URI);
+ }
+ public Module parse(Element elem) {
+ boolean foundSomething = false;
+ PubControlModule m = new PubControlModuleImpl();
+ Element e = elem.getChild("control", getContentNamespace());
+ if (e != null) {
+ Element draftElem = e.getChild("draft", getContentNamespace());
+ if (draftElem != null) {
+ if ("yes".equals(draftElem.getText())) m.setDraft(true);
+ if ("no".equals(draftElem.getText())) m.setDraft(false);
+ }
+ }
+ return m;
+ }
+}
+
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/RollerAtomHandler.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/RollerAtomHandler.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/RollerAtomHandler.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/RollerAtomHandler.java Mon May 1 15:23:02 2006
@@ -0,0 +1,837 @@
+/*
+ * 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.
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+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.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.model.FileManager;
+import org.apache.roller.model.Roller;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.PermissionsData;
+import org.apache.roller.pojos.WeblogCategoryData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.RollerContext;
+import org.apache.roller.util.RollerMessages;
+import org.apache.roller.util.Utilities;
+
+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 javax.activation.FileTypeMap;
+import org.apache.roller.RollerException;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.model.WeblogManager;
+import org.apache.roller.presentation.cache.CacheManager;
+
+/**
+ * Roller's Atom Protocol implementation.
+ * <pre>
+ * Here are the URIs suppored:
+ *
+ * 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
+ */
+public class RollerAtomHandler implements AtomHandler {
+ private HttpServletRequest mRequest;
+ private Roller mRoller;
+ private RollerContext mRollerContext;
+ private UserData user;
+ private int mMaxEntries = 20;
+ //private MessageDigest md5Helper = null;
+ //private MD5Encoder md5Encoder = new MD5Encoder();
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(RollerAtomHandler.class);
+
+ //---------------------------------------------------------------- construction
+
+ /**
+ * Create Atom handler for a request and attempt to authenticate user.
+ * If user is authenticated, then getAuthenticatedUsername() will return
+ * then user's name, otherwise it will return null.
+ */
+ public RollerAtomHandler(HttpServletRequest request) {
+ mRequest = request;
+ mRoller = RollerFactory.getRoller();
+ 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) {
+ try {
+ this.user = mRoller.getUserManager().getUserByUsername(mUsername);
+ } catch (Exception e) {
+ mLogger.error("ERROR: setting user", e);
+ }
+ }
+ }
+
+ /**
+ * Return weblogHandle of authenticated user or null if there is none.
+ */
+ public String getAuthenticatedUsername() {
+ return this.user.getUserName();
+ }
+
+ //---------------------------------------------------------------- introspection
+
+ /**
+ * 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 = mRollerContext.getAbsoluteContextUrl(mRequest);
+ 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);
+ }
+ }
+ return service;
+ }
+ throw new Exception("ERROR: bad URL in getIntrospection()");
+ }
+
+ //----------------------------------------------------------------- collections
+
+ /**
+ * Return collection specified by pathinfo.
+ * <pre>
+ * Supports these URI forms:
+ * /<blog-name>/entries
+ * /<blog-name>/entries/offset
+ * /<blog-name>/resources
+ * /<blog-name>/resources/offset
+ * </pre>
+ */
+ public Feed getCollection(String[] pathInfo) throws Exception {
+ int start = 0;
+ if (pathInfo.length > 2) {
+ try {
+ String s = pathInfo[2].trim();
+ start = Integer.parseInt(s);
+ } catch (Throwable t) {
+ mLogger.warn("Unparsable range: " + pathInfo[2]);
+ }
+ }
+ if (pathInfo.length > 0 && pathInfo[1].equals("entries")) {
+ return getCollectionOfEntries(pathInfo, start, mMaxEntries);
+ } else if (pathInfo.length > 0 && pathInfo[1].equals("resources")) {
+ return getCollectionOfResources(pathInfo, start, mMaxEntries);
+ }
+ throw new Exception("ERROR: bad URL in getCollection()");
+ }
+
+ /**
+ * 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 = mRollerContext.getAbsoluteContextUrl(mRequest);
+ WebsiteData website = mRoller.getUserManager().getWebsiteByHandle(handle);
+ List entries = null;
+ if (canView(website)) {
+ entries = mRoller.getWeblogManager().getWeblogEntries(
+ website, // website
+ null, // startDate
+ null, // endDate
+ null, // catName
+ null, // status
+ "updateTime", // sortby
+ start, // offset (for range paging)
+ max + 1); // maxEntries
+ 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;
+ }
+ 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 = mRollerContext.getAbsoluteContextUrl(mRequest);
+ 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]);
+ atomEntries.add(entry);
+ count++;
+ }
+ }
+ 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 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);
+
+ CacheManager.invalidate(website);
+ if (rollerEntry.isPublished()) {
+ mRoller.getIndexManager().addEntryReIndexOperation(rollerEntry);
+ }
+ return createAtomEntry(rollerEntry);
+ }
+ 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);
+ }
+ return null;
+ }
+ 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 =
+ 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);
+ }
+ throw new Exception("ERROR not authorized to put 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();
+ return;
+ }
+ throw new Exception("ERROR not authorized to delete entry");
+ }
+ throw new Exception("ERROR: bad URI");
+ }
+
+ //-------------------------------------------------------------------- resources
+
+ /**
+ * Create new resource in generic collection (a Roller 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 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);
+ }
+
+ } catch (Exception e) {
+ String msg = "ERROR in atom.postResource";
+ mLogger.error(msg,e);
+ throw new Exception(msg);
+ } finally {
+ if (tempFile != null) tempFile.delete();
+ }
+ }
+ 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
+ */
+ public Entry putMedia(String[] pathInfo,
+ String contentType, InputStream is) throws Exception {
+ 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");
+ }
+
+ //------------------------------------------------------------------ URI testers
+
+ /**
+ * True if URL is the introspection URI.
+ */
+ public boolean isIntrospectionURI(String[] pathInfo) {
+ if (pathInfo.length==0) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a entry URI.
+ */
+ public boolean isEntryURI(String[] pathInfo) {
+ if (pathInfo.length > 1 && pathInfo[1].equals("entry")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a resource URI.
+ */
+ public boolean isMediaURI(String[] pathInfo) {
+ if (pathInfo.length > 1 && pathInfo[1].equals("resource")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a category URI.
+ */
+ public boolean isCategoryURI(String[] pathInfo) {
+ if (pathInfo.length > 1 && pathInfo[1].equals("category")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a collection URI of any sort.
+ */
+ public boolean isCollectionURI(String[] pathInfo) {
+ if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
+ if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
+ if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
+ 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
+
+ /**
+ * Return true if user is allowed to edit an entry.
+ */
+ private boolean canEdit(WeblogEntryData entry) {
+ try {
+ return entry.hasWritePermissions(this.user);
+ } catch (Exception e) {
+ mLogger.error("ERROR: checking website.canSave()");
+ }
+ return false;
+ }
+
+ /**
+ * Return true if user is allowed to create/edit weblog entries and file uploads in a website.
+ */
+ private boolean canEdit(WebsiteData website) {
+ try {
+ return website.hasUserPermissions(this.user, PermissionsData.AUTHOR);
+ } catch (Exception e) {
+ mLogger.error("ERROR: checking website.hasUserPermissions()");
+ }
+ return false;
+ }
+
+ /**
+ * Return true if user is allowed to view an entry.
+ */
+ private boolean canView(WeblogEntryData entry) {
+ return canEdit(entry);
+ }
+
+ /**
+ * Return true if user is allowed to view a website.
+ */
+ private boolean canView(WebsiteData website) {
+ return canEdit(website);
+ }
+
+ //-------------------------------------------------------------- authentication
+
+ /**
+ * Perform WSSE authentication based on information in request.
+ * Will not work if Roller password encryption is turned on.
+ */
+ protected String authenticateWSSE(HttpServletRequest request) {
+ String wsseHeader = request.getHeader("X-WSSE");
+ if (wsseHeader == null) return null;
+
+ String ret = null;
+ String userName = null;
+ String created = null;
+ String nonce = null;
+ String passwordDigest = null;
+ String[] tokens = wsseHeader.split(",");
+ for (int i = 0; i < tokens.length; i++) {
+ int index = tokens[i].indexOf('=');
+ if (index != -1) {
+ String key = tokens[i].substring(0, index).trim();
+ String value = tokens[i].substring(index + 1).trim();
+ value = value.replaceAll("\"", "");
+ if (key.startsWith("UsernameToken")) {
+ userName = value;
+ } else if (key.equalsIgnoreCase("nonce")) {
+ nonce = value;
+ } else if (key.equalsIgnoreCase("passworddigest")) {
+ passwordDigest = value;
+ } else if (key.equalsIgnoreCase("created")) {
+ created = value;
+ }
+ }
+ }
+ String digest = null;
+ try {
+ UserData user = mRoller.getUserManager().getUserByUsername(userName);
+ digest = WSSEUtilities.generateDigest(
+ WSSEUtilities.base64Decode(nonce),
+ created.getBytes("UTF-8"),
+ user.getPassword().getBytes("UTF-8"));
+ if (digest.equals(passwordDigest)) {
+ ret = userName;
+ }
+ } catch (Exception e) {
+ mLogger.error("ERROR in wsseAuthenticataion: " + e.getMessage(), e);
+ }
+ return ret;
+ }
+
+ /**
+ * Untested (and currently unused) implementation of BASIC authentication
+ */
+ public String authenticateBASIC(HttpServletRequest request) {
+ boolean valid = false;
+ String userID = null;
+ String password = null;
+ try {
+ String authHeader = request.getHeader("Authorization");
+ if (authHeader != null) {
+ StringTokenizer st = new StringTokenizer(authHeader);
+ if (st.hasMoreTokens()) {
+ String basic = st.nextToken();
+ if (basic.equalsIgnoreCase("Basic")) {
+ String credentials = st.nextToken();
+ String userPass = new String(Base64.decodeBase64(credentials.getBytes()));
+ int p = userPass.indexOf(":");
+ if (p != -1) {
+ userID = userPass.substring(0, p);
+ UserData user = mRoller.getUserManager().getUserByUsername(userID);
+ boolean enabled = user.getEnabled().booleanValue();
+ if (enabled) {
+ // are passwords encrypted?
+ 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"));
+ }
+ valid = user.getPassword().equals(password);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ mLogger.debug(e);
+ }
+ if (valid) return userID;
+ return null;
+ }
+
+ //----------------------------------------------------------- internal utilities
+
+ /**
+ * Create a Rome Atom entry based on a Roller entry.
+ * Content is escaped.
+ * Link is stored as rel=alternate link.
+ */
+ private Entry createAtomEntry(WeblogEntryData entry) {
+ Entry atomEntry = new Entry();
+ Content content = new Content();
+ content.setType(Content.HTML);
+ content.setValue(entry.getText());
+ List contents = new ArrayList();
+ contents.add(content);
+
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+ atomEntry.setId( absUrl + entry.getPermaLink());
+ atomEntry.setTitle( entry.getTitle());
+ atomEntry.setContents( contents);
+ atomEntry.setPublished( entry.getPubTime());
+ atomEntry.setUpdated( entry.getUpdateTime());
+
+ UserData creator = entry.getCreator();
+ Person author = new Person();
+ author.setName( creator.getUserName());
+ author.setEmail( creator.getEmailAddress());
+ atomEntry.setAuthors( Collections.singletonList(author));
+
+ List categories = new ArrayList();
+ Category atomCat = new Category();
+ atomCat.setTerm(entry.getCategory().getPath());
+ categories.add(atomCat);
+ 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(absUrl + "/app/"
+ + entry.getWebsite().getHandle() + "/entry/" + entry.getId());
+ List otherlinks = new ArrayList();
+ otherlinks.add(editlink);
+ atomEntry.setOtherLinks(otherlinks);
+
+ List modules = new ArrayList();
+ PubControlModule pubControl = new PubControlModuleImpl();
+ pubControl.setDraft(
+ !WeblogEntryData.PUBLISHED.equals(entry.getStatus()));
+ modules.add(pubControl);
+ atomEntry.setModules(modules);
+
+ return atomEntry;
+ }
+
+ private Entry createAtomResourceEntry(WebsiteData website, File file) {
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+ String editURI = absUrl
+ + "/app/" + website.getHandle()
+ + "/resource/" + file.getName();
+ String viewURI = absUrl
+ + "/resources/" + website.getHandle()
+ + "/" + file.getName();
+ FileTypeMap map = FileTypeMap.getDefaultFileTypeMap();
+ String contentType = map.getContentType(file);
+
+ Entry entry = new Entry();
+ 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);
+ entry.setOtherLinks(otherlinks);
+
+ Content content = new Content();
+ content.setSrc(viewURI);
+ content.setType(contentType);
+ List contents = new ArrayList();
+ contents.add(content);
+ entry.setContents(contents);
+
+ return entry;
+ }
+
+ /**
+ * Create a Roller weblog entry based on a Rome Atom entry object
+ */
+ private WeblogEntryData createRollerEntry(WebsiteData website, Entry entry)
+ throws RollerException {
+
+ 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() );
+ }
+ WeblogEntryData rollerEntry = new WeblogEntryData();
+ rollerEntry.setTitle(entry.getTitle());
+ if (entry.getContents() != null && entry.getContents().size() > 0) {
+ Content content = (Content)entry.getContents().get(0);
+ rollerEntry.setText(content.getValue());
+ }
+ rollerEntry.setPubTime(pubTime);
+ rollerEntry.setUpdateTime(updateTime);
+ rollerEntry.setWebsite(website);
+
+ PubControlModule control =
+ (PubControlModule)entry.getModule("http://purl.org/atom/app#");
+ if (control!=null && control.getDraft()) {
+ rollerEntry.setStatus(WeblogEntryData.DRAFT);
+ } else {
+ rollerEntry.setStatus(WeblogEntryData.PUBLISHED);
+ }
+
+ // Atom supports multiple cats, Roller 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);
+ // Caller has no way of knowing our categories, so be lenient here
+ String catString = cat.getTerm() != null ? cat.getTerm() : cat.getLabel();
+ if (catString != null) {
+ WeblogCategoryData rollerCat =
+ mRoller.getWeblogManager().getWeblogCategoryByPath(
+ website, catString);
+ if (rollerCat != null) {
+ // Found a valid category, so break out
+ rollerEntry.setCategory(rollerCat);
+ break;
+ }
+ }
+ }
+ } else {
+ // or we fall back to the default Blogger API category
+ rollerEntry.setCategory(website.getBloggerCategory());
+ }
+ return rollerEntry;
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/WSSEUtilities.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/WSSEUtilities.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/WSSEUtilities.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/WSSEUtilities.java Mon May 1 15:23:02 2006
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2005, Dave Johnson
+ *
+ * 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.
+ */
+package org.apache.roller.presentation.webservices.atomprotocol;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * Utilties to support WSSE authentication.
+ * @author Dave Johnson
+ */
+public class WSSEUtilities {
+ public static synchronized String generateDigest(
+ byte[] nonce, byte[] created, byte[] password) {
+ String result = null;
+ try {
+ MessageDigest digester = MessageDigest.getInstance("SHA");
+ digester.reset();
+ digester.update(nonce);
+ digester.update(created);
+ digester.update(password);
+ byte[] digest = digester.digest();
+ result = new String(base64Encode(digest));
+ }
+ catch (NoSuchAlgorithmException e) {
+ result = null;
+ }
+ return result;
+ }
+ public static byte[] base64Decode(String value) throws IOException {
+ return Base64.decodeBase64(value.getBytes("UTF-8"));
+ }
+ public static String base64Encode(byte[] value) {
+ return new String(Base64.encodeBase64(value));
+ }
+ public static String generateWSSEHeader(String userName, String password)
+ throws UnsupportedEncodingException {
+
+ byte[] nonceBytes = Long.toString(new Date().getTime()).getBytes();
+ String nonce = new String(WSSEUtilities.base64Encode(nonceBytes));
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String created = sdf.format(new Date());
+
+ String digest = WSSEUtilities.generateDigest(
+ nonceBytes, created.getBytes("UTF-8"), password.getBytes("UTF-8"));
+
+ StringBuffer header = new StringBuffer("UsernameToken Username=\"");
+ header.append(userName);
+ header.append("\", ");
+ header.append("PasswordDigest=\"");
+ header.append(digest);
+ header.append("\", ");
+ header.append("Nonce=\"");
+ header.append(nonce);
+ header.append("\", ");
+ header.append("Created=\"");
+ header.append(created);
+ header.append("\"");
+ return header.toString();
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/package.html?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/package.html (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/atomprotocol/package.html Mon May 1 15:23:02 2006
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title></title>
+</head>
+<body>
+ROME-based Atom Protocol implementation.
+
+</body>
+</html>
Added: incubator/roller/trunk/src/org/apache/roller/presentation/webservices/xmlrpc/BaseAPIHandler.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/webservices/xmlrpc/BaseAPIHandler.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/webservices/xmlrpc/BaseAPIHandler.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/webservices/xmlrpc/BaseAPIHandler.java Mon May 1 15:23:02 2006
@@ -0,0 +1,260 @@
+/*
+* 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.
+*/
+/*
+ * Created on Apr 11, 2003
+ */
+package org.apache.roller.presentation.webservices.xmlrpc;
+
+import java.io.Serializable;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.UserManager;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.RollerContext;
+import org.apache.roller.presentation.RollerRequest;
+import org.apache.roller.presentation.cache.CacheManager;
+import org.apache.roller.util.Utilities;
+
+/**
+ * Base API handler does user validation, provides exception types, etc.
+ * @author David M Johnson
+ */
+public class BaseAPIHandler implements Serializable
+{
+ static final long serialVersionUID = -698186274794937582L;
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(BaseAPIHandler.class);
+
+ public static final int AUTHORIZATION_EXCEPTION = 0001;
+ public static final String AUTHORIZATION_EXCEPTION_MSG =
+ "Invalid Username and/or Password";
+
+ public static final int UNKNOWN_EXCEPTION = 1000;
+ public static final String UNKNOWN_EXCEPTION_MSG =
+ "An error occured processing your request";
+
+ public static final int UNSUPPORTED_EXCEPTION = 1001;
+ public static final String UNSUPPORTED_EXCEPTION_MSG =
+ "Unsupported method - Roller does not support this method";
+
+ public static final int USER_DISABLED = 1002;
+ public static final String USER_DISABLED_MSG =
+ "User is disabled";
+
+ public static final int WEBLOG_NOT_FOUND = 1003;
+ public static final String WEBLOG_NOT_FOUND_MSG =
+ "Weblog is not found or is disabled";
+
+ public static final int WEBLOG_DISABLED = 1004;
+ public static final String WEBLOG_DISABLED_MSG =
+ "Weblog is not found or is disabled";
+
+ public static final int BLOGGERAPI_DISABLED = 1005;
+ public static final String BLOGGERAPI_DISABLED_MSG =
+ "Weblog does not exist or XML-RPC disabled in web";
+
+ public static final int BLOGGERAPI_INCOMPLETE_POST = 1006;
+ public static final String BLOGGERAPI_INCOMPLETE_POST_MSG =
+ "Incomplete weblog entry";
+
+ public static final int INVALID_POSTID = 2000;
+ public static final String INVALID_POSTID_MSG =
+ "The entry postid you submitted is invalid";
+
+ //public static final int NOBLOGS_EXCEPTION = 3000;
+ //public static final String NOBLOGS_EXCEPTION_MSG =
+ //"There are no categories defined for your user";
+
+ public static final int UPLOAD_DENIED_EXCEPTION = 4000;
+ public static final String UPLOAD_DENIED_EXCEPTION_MSG =
+ "Upload denied";
+
+ //------------------------------------------------------------------------
+ public BaseAPIHandler()
+ {
+ }
+
+ //------------------------------------------------------------------------
+ //public void prep( HttpServletRequest req )
+ //{
+ //mRoller = RollerContext.getRoller(req);
+ //mContextUrl = RollerContext.getRollerContext(req).getAbsoluteContextUrl(req);
+ //
+
+ //------------------------------------------------------------------------
+ /**
+ * Returns website, but only if user authenticates and is authorized to edit.
+ * @param blogid Blogid sent in request (used as website's hanldle)
+ * @param username Username sent in request
+ * @param password Password sent in requeset
+ */
+ protected WebsiteData validate(String blogid, String username, String password)
+ throws Exception
+ {
+ boolean authenticated = false;
+ boolean userEnabled = false;
+ boolean weblogEnabled = false;
+ boolean apiEnabled = false;
+ boolean weblogFound = false;
+ WebsiteData website = null;
+ UserData user = null;
+ try
+ {
+ // Get Roller request object for current thread
+ RollerRequest rreq = RollerRequest.getRollerRequest();
+
+ UserManager userMgr = RollerFactory.getRoller().getUserManager();
+ user = userMgr.getUserByUsername(username);
+ userEnabled = user.getEnabled().booleanValue();
+
+ website = userMgr.getWebsiteByHandle(blogid);
+ if (website != null) {
+ weblogFound = true;
+ weblogEnabled = website.getEnabled().booleanValue();
+ apiEnabled = website.getEnableBloggerApi().booleanValue();
+ }
+
+ if (user != null)
+ {
+ // are passwords encrypted?
+ RollerContext rollerContext =
+ RollerContext.getRollerContext();
+ String encrypted =
+ RollerConfig.getProperty("passwds.encryption.enabled");
+ //System.out.print("password was [" + password + "] ");
+ if ("true".equalsIgnoreCase(encrypted))
+ {
+ password = Utilities.encodePassword(password,
+ RollerConfig.getProperty("passwds.encryption.algorithm"));
+ }
+ //System.out.println("is now [" + password + "]");
+ authenticated= user.getPassword().equals(password);
+ if (authenticated)
+ {
+ //RollerFactory.getRoller().setUser(user);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR internal error validating user", e);
+ }
+
+ if ( !authenticated )
+ {
+ throw new XmlRpcException(
+ AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
+ }
+ if ( !userEnabled )
+ {
+ throw new XmlRpcException(
+ USER_DISABLED, USER_DISABLED_MSG);
+ }
+ if ( !weblogEnabled )
+ {
+ throw new XmlRpcException(
+ WEBLOG_DISABLED, WEBLOG_DISABLED_MSG);
+ }
+ if ( !weblogFound )
+ {
+ throw new XmlRpcException(
+ WEBLOG_NOT_FOUND, WEBLOG_NOT_FOUND_MSG);
+ }
+ if ( !apiEnabled )
+ {
+ throw new XmlRpcException(
+ BLOGGERAPI_DISABLED, BLOGGERAPI_DISABLED_MSG);
+ }
+ return website;
+ }
+
+ //------------------------------------------------------------------------
+ /**
+ * Returns true if username/password are valid and user is not disabled.
+ * @param username Username sent in request
+ * @param password Password sent in requeset
+ */
+ protected boolean validateUser(String username, String password)
+ throws Exception
+ {
+ boolean authenticated = false;
+ boolean enabled = false;
+ UserData user = null;
+ try
+ {
+ // Get Roller request object for current thread
+ RollerRequest rreq = RollerRequest.getRollerRequest();
+
+ UserManager userMgr = RollerFactory.getRoller().getUserManager();
+ user = userMgr.getUserByUsername(username);
+
+ enabled = user.getEnabled().booleanValue();
+ if (enabled)
+ {
+ // are passwords encrypted?
+ RollerContext rollerContext =
+ RollerContext.getRollerContext();
+ String encrypted =
+ RollerConfig.getProperty("passwds.encryption.enabled");
+ //System.out.print("password was [" + password + "] ");
+ if ("true".equalsIgnoreCase(encrypted))
+ {
+ password = Utilities.encodePassword(password,
+ RollerConfig.getProperty("passwds.encryption.algorithm"));
+ }
+ //System.out.println("is now [" + password + "]");
+ authenticated = user.getPassword().equals(password);
+ if (authenticated)
+ {
+ //RollerFactory.getRoller().setUser(user);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR internal error validating user", e);
+ }
+
+ if ( !enabled )
+ {
+ throw new XmlRpcException(
+ BLOGGERAPI_DISABLED, BLOGGERAPI_DISABLED_MSG);
+ }
+
+ if ( !authenticated )
+ {
+ throw new XmlRpcException(
+ AUTHORIZATION_EXCEPTION, AUTHORIZATION_EXCEPTION_MSG);
+ }
+ return authenticated;
+ }
+
+ //------------------------------------------------------------------------
+ protected void flushPageCache(WebsiteData website) throws Exception
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest();
+ //PageCacheFilter.removeFromCache( rreq.getRequest(), website);
+ CacheManager.invalidate(website);
+ }
+}