From 4a4113127b3711ecc030d741b9a3b8be53b6571d Mon Sep 17 00:00:00 2001 From: kebernet Date: Fri, 1 Apr 2011 04:58:03 +0000 Subject: [PATCH] Package move. --- .../atom/client/AtomClientFactory.java | 47 - .../propono/atom/client/AuthStrategy.java | 30 - .../atom/client/BasicAuthStrategy.java | 41 - .../atom/client/ClientAtomService.java | 138 --- .../propono/atom/client/ClientCategories.java | 70 -- .../propono/atom/client/ClientCollection.java | 217 ----- .../propono/atom/client/ClientEntry.java | 259 ------ .../propono/atom/client/ClientMediaEntry.java | 322 ------- .../propono/atom/client/ClientWorkspace.java | 66 -- .../propono/atom/client/EntryIterator.java | 124 --- .../atom/client/GDataAuthStrategy.java | 67 -- .../propono/atom/client/NoAuthStrategy.java | 31 - .../propono/atom/client/OAuthStrategy.java | 302 ------- .../atom/client/atomclient-diagram.gif | Bin 19120 -> 0 bytes .../propono/atom/common/AtomService.java | 122 --- .../propono/atom/common/Categories.java | 155 ---- .../propono/atom/common/Collection.java | 252 ------ .../propono/atom/common/Workspace.java | 147 --- .../propono/atom/common/rome/AppModule.java | 42 - .../atom/common/rome/AppModuleGenerator.java | 85 -- .../atom/common/rome/AppModuleImpl.java | 69 -- .../atom/common/rome/AppModuleParser.java | 66 -- .../propono/atom/server/AtomException.java | 53 -- .../propono/atom/server/AtomHandler.java | 144 --- .../atom/server/AtomHandlerFactory.java | 113 --- .../atom/server/AtomMediaResource.java | 95 -- .../server/AtomNotAuthorizedException.java | 49 - .../atom/server/AtomNotFoundException.java | 48 - .../propono/atom/server/AtomRequest.java | 139 --- .../propono/atom/server/AtomRequestImpl.java | 114 --- .../propono/atom/server/AtomServlet.java | 378 -------- .../server/FactoryConfigurationError.java | 106 --- .../propono/atom/server/FactoryFinder.java | 280 ------ .../propono/atom/server/SecuritySupport.java | 90 -- .../server/impl/FileBasedAtomHandler.java | 443 --------- .../impl/FileBasedAtomHandlerFactory.java | 37 - .../server/impl/FileBasedAtomService.java | 188 ---- .../atom/server/impl/FileBasedCollection.java | 837 ------------------ .../atom/server/impl/FileBasedWorkspace.java | 34 - .../propono/atom/server/impl/FileStore.java | 116 --- .../propono/blogclient/BaseBlogEntry.java | 193 ---- .../syndication/propono/blogclient/Blog.java | 213 ----- .../blogclient/BlogClientException.java | 40 - .../propono/blogclient/BlogConnection.java | 34 - .../blogclient/BlogConnectionFactory.java | 80 -- .../propono/blogclient/BlogEntry.java | 231 ----- .../propono/blogclient/BlogResource.java | 39 - .../blogclient/atomprotocol/AtomBlog.java | 206 ----- .../atomprotocol/AtomCollection.java | 165 ---- .../atomprotocol/AtomConnection.java | 92 -- .../blogclient/atomprotocol/AtomEntry.java | 240 ----- .../atomprotocol/AtomEntryIterator.java | 72 -- .../blogclient/atomprotocol/AtomResource.java | 134 --- .../propono/blogclient/blogclient-diagram.gif | Bin 18568 -> 0 bytes .../blogclient/metaweblog/MetaWeblogBlog.java | 436 --------- .../metaweblog/MetaWeblogConnection.java | 105 --- .../metaweblog/MetaWeblogEntry.java | 122 --- .../metaweblog/MetaWeblogResource.java | 112 --- .../propono/utils/ProponoException.java | 153 ---- .../syndication/propono/utils/Utilities.java | 268 ------ 60 files changed, 8851 deletions(-) delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/AtomClientFactory.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/AuthStrategy.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/BasicAuthStrategy.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientAtomService.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientCategories.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientCollection.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientMediaEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/ClientWorkspace.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/EntryIterator.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/GDataAuthStrategy.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/NoAuthStrategy.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/OAuthStrategy.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/client/atomclient-diagram.gif delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/AtomService.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/Categories.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/Collection.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/Workspace.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/rome/AppModule.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleGenerator.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleImpl.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleParser.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomException.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomHandler.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomHandlerFactory.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomMediaResource.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomNotAuthorizedException.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomNotFoundException.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomRequest.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomRequestImpl.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/AtomServlet.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/FactoryConfigurationError.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/FactoryFinder.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/SecuritySupport.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandler.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandlerFactory.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomService.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedCollection.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedWorkspace.java delete mode 100644 src/main/java/com/sun/syndication/propono/atom/server/impl/FileStore.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BaseBlogEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/Blog.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BlogClientException.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BlogConnection.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BlogConnectionFactory.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BlogEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/BlogResource.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomBlog.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomCollection.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomConnection.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntryIterator.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomResource.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/blogclient-diagram.gif delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogBlog.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogConnection.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogEntry.java delete mode 100644 src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogResource.java delete mode 100644 src/main/java/com/sun/syndication/propono/utils/ProponoException.java delete mode 100644 src/main/java/com/sun/syndication/propono/utils/Utilities.java diff --git a/src/main/java/com/sun/syndication/propono/atom/client/AtomClientFactory.java b/src/main/java/com/sun/syndication/propono/atom/client/AtomClientFactory.java deleted file mode 100644 index 4e7935b..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/AtomClientFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.utils.ProponoException; -import com.sun.syndication.io.impl.Atom10Parser; - - -/** - * Creates AtomService or ClientCollection based on username, password and - * end-point URI of Atom protocol service. - */ -public class AtomClientFactory { - - static { - Atom10Parser.setResolveURIs(true); - } - - /** - * Create AtomService by reading service doc from Atom Server. - */ - public static ClientAtomService getAtomService( - String uri, AuthStrategy authStrategy) throws ProponoException { - return new ClientAtomService(uri, authStrategy); - } - - /** - * Create ClientCollection bound to URI. - */ - public static ClientCollection getCollection( - String uri, AuthStrategy authStrategy) throws ProponoException { - return new ClientCollection(uri, authStrategy); - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/AuthStrategy.java b/src/main/java/com/sun/syndication/propono/atom/client/AuthStrategy.java deleted file mode 100644 index e8bd37f..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/AuthStrategy.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.utils.ProponoException; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; - - -public interface AuthStrategy { - - /** - * Add authentication credenticals, tokens, etc. to HTTP method - */ - void addAuthentication(HttpClient httpClient, HttpMethodBase method) - throws ProponoException; -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/BasicAuthStrategy.java b/src/main/java/com/sun/syndication/propono/atom/client/BasicAuthStrategy.java deleted file mode 100644 index ce200f5..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/BasicAuthStrategy.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2009 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.io.impl.Base64; -import com.sun.syndication.propono.utils.ProponoException; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; - - -public class BasicAuthStrategy implements AuthStrategy { - private String credentials; - - public BasicAuthStrategy(String username, String password) { - this.credentials = - new String(new Base64().encode((username + ":" + password).getBytes())); - } - - public void init() throws ProponoException { - // op-op - } - - public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { - httpClient.getParams().setAuthenticationPreemptive(true); - String header = "Basic " + credentials; - method.setRequestHeader("Authorization", header); - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/ClientAtomService.java b/src/main/java/com/sun/syndication/propono/atom/client/ClientAtomService.java deleted file mode 100644 index 873d824..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/ClientAtomService.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.io.impl.Atom10Parser; -import com.sun.syndication.propono.utils.ProponoException; -import com.sun.syndication.propono.atom.common.AtomService; -import java.io.InputStreamReader; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.input.SAXBuilder; - - -/** - * This class models an Atom Publising Protocol Service Document. - * It extends the common - * {@link com.sun.syndication.propono.atom.common.Collection} - * class to add a getEntry() method and to return - * {@link com.sun.syndication.propono.atom.client.ClientWorkspace} - * objects instead of common - * {@link com.sun.syndication.propono.atom.common.Workspace}s. - */ -public class ClientAtomService extends AtomService { - private static Log logger = LogFactory.getLog(ClientAtomService.class); - private String uri = null; - private HttpClient httpClient = null; - private AuthStrategy authStrategy = null; - - /** - * Create Atom blog service instance for specified URL and user account. - * @param url End-point URL of Atom service - */ - ClientAtomService(String uri, AuthStrategy authStrategy) - throws ProponoException { - this.uri = uri; - this.authStrategy = authStrategy; - Document doc = getAtomServiceDocument(); - parseAtomServiceDocument(doc); - } - - /** - * Get full entry from service by entry edit URI. - */ - public ClientEntry getEntry(String uri) throws ProponoException { - GetMethod method = new GetMethod(uri); - authStrategy.addAuthentication(httpClient, method); - try { - httpClient.executeMethod(method); - if (method.getStatusCode() != 200) { - throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); - } - Entry romeEntry = Atom10Parser.parseEntry( - new InputStreamReader(method.getResponseBodyAsStream()), uri); - if (!romeEntry.isMediaEntry()) { - return new ClientEntry(this, null, romeEntry, false); - } else { - return new ClientMediaEntry(this, null, romeEntry, false); - } - } catch (Exception e) { - throw new ProponoException("ERROR: getting or parsing entry/media", e); - } finally { - method.releaseConnection(); - } - } - - void addAuthentication(HttpMethodBase method) throws ProponoException { - authStrategy.addAuthentication(httpClient, method); - } - - AuthStrategy getAuthStrategy() { - return authStrategy; - } - - private Document getAtomServiceDocument() throws ProponoException { - GetMethod method = null; - int code = -1; - try { - httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); - // TODO: make connection timeout configurable - httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); - - method = new GetMethod(uri); - authStrategy.addAuthentication(httpClient, method); - httpClient.executeMethod(method); - - SAXBuilder builder = new SAXBuilder(); - return builder.build(method.getResponseBodyAsStream()); - - } catch (Throwable t) { - String msg = "ERROR retrieving Atom Service Document, code: "+code; - logger.debug(msg, t); - throw new ProponoException(msg, t); - } finally { - if (method != null) method.releaseConnection(); - } - } - - /** Deserialize an Atom service XML document into an object */ - private void parseAtomServiceDocument(Document document) throws ProponoException { - Element root = document.getRootElement(); - List spaces = root.getChildren("workspace", AtomService.ATOM_PROTOCOL); - Iterator iter = spaces.iterator(); - while (iter.hasNext()) { - Element e = (Element) iter.next(); - addWorkspace(new ClientWorkspace(e, this, uri)); - } - } - - /** - * Package access to httpClient. - */ - HttpClient getHttpClient() { - return httpClient; - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/client/ClientCategories.java b/src/main/java/com/sun/syndication/propono/atom/client/ClientCategories.java deleted file mode 100644 index 965d1ca..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/ClientCategories.java +++ /dev/null @@ -1,70 +0,0 @@ -/* -* 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.feed.atom.Category; -import com.sun.syndication.propono.atom.common.*; -import com.sun.syndication.propono.utils.ProponoException; -import java.io.IOException; -import java.io.InputStreamReader; -import org.apache.commons.httpclient.methods.GetMethod; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.input.SAXBuilder; - - -/** - * Models an Atom protocol Categories element, which may contain ROME Atom - * {@link com.sun.syndication.feed.atom.Category} elements. - */ -public class ClientCategories extends Categories { - private ClientCollection clientCollection = null; - - /** Load select from XML element */ - public ClientCategories(Element e, ClientCollection clientCollection) throws ProponoException { - this.clientCollection = clientCollection; - parseCategoriesElement(e); - if (getHref() != null) fetchContents(); - } - - public void fetchContents() throws ProponoException { - GetMethod method = new GetMethod(getHrefResolved()); - clientCollection.addAuthentication(method); - try { - clientCollection.getHttpClient().executeMethod(method); - if (method.getStatusCode() != 200) { - throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); - } - SAXBuilder builder = new SAXBuilder(); - Document catsDoc = builder.build( - new InputStreamReader(method.getResponseBodyAsStream())); - parseCategoriesElement(catsDoc.getRootElement()); - - } catch (IOException ioe) { - throw new ProponoException( - "ERROR: reading out-of-line categories", ioe); - } catch (JDOMException jde) { - throw new ProponoException( - "ERROR: parsing out-of-line categories", jde); - } finally { - method.releaseConnection(); - } - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/client/ClientCollection.java b/src/main/java/com/sun/syndication/propono/atom/client/ClientCollection.java deleted file mode 100644 index 94b270a..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/ClientCollection.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.io.InputStreamReader; -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.io.impl.Atom10Parser; -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.atom.common.Categories; -import com.sun.syndication.propono.utils.ProponoException; -import com.sun.syndication.propono.atom.common.Collection; -import com.sun.syndication.propono.atom.common.Workspace; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.methods.GetMethod; -import org.jdom.Element; - -/** - * Models an Atom collection, extends Collection and adds methods for adding, - * retrieving, updateing and deleting entries. - */ -public class ClientCollection extends Collection { - static final Log logger = LogFactory.getLog(ClientCollection.class); - - private List categories = new ArrayList(); - private HttpClient httpClient = null; - private AuthStrategy authStrategy = null; - private boolean writable = true; - - private ClientWorkspace workspace = null; - private ClientAtomService service = null; - - ClientCollection(Element e, ClientWorkspace workspace, String baseURI) throws ProponoException { - super(e, baseURI); - this.workspace = workspace; - this.service = workspace.getAtomService(); - this.httpClient = workspace.getAtomService().getHttpClient(); - this.authStrategy = workspace.getAtomService().getAuthStrategy(); - parseCollectionElement(e); - } - - ClientCollection(String href, AuthStrategy authStrategy) throws ProponoException { - super("Standalone connection", "text", href); - this.authStrategy = authStrategy; - try { - httpClient = new HttpClient(new MultiThreadedHttpConnectionManager()); - // TODO: make connection timeout configurable - httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); - } catch (Throwable t) { - throw new ProponoException("ERROR creating HTTPClient", t); - } - } - - void addAuthentication(HttpMethodBase method) throws ProponoException { - authStrategy.addAuthentication(httpClient, method); - } - - /** - * Package access to httpClient to allow use by ClientEntry and ClientMediaEntry. - */ - HttpClient getHttpClient() { - return httpClient; - } - - /** - * Get iterator over entries in this collection. Entries returned are - * considered to be partial entries cannot be saved/updated. - */ - public Iterator getEntries() throws ProponoException { - return new EntryIterator(this); - } - - /** - * Get full entry specified by entry edit URI. - * Note that entry may or may not be associated with this collection. - * @return ClientEntry or ClientMediaEntry specified by URI. - */ - public ClientEntry getEntry(String uri) throws ProponoException { - GetMethod method = new GetMethod(uri); - authStrategy.addAuthentication(httpClient, method); - try { - httpClient.executeMethod(method); - if (method.getStatusCode() != 200) { - throw new ProponoException("ERROR HTTP status code=" + method.getStatusCode()); - } - Entry romeEntry = Atom10Parser.parseEntry( - new InputStreamReader(method.getResponseBodyAsStream()), uri); - if (!romeEntry.isMediaEntry()) { - return new ClientEntry(service, this, romeEntry, false); - } else { - return new ClientMediaEntry(service, this, romeEntry, false); - } - } catch (Exception e) { - throw new ProponoException("ERROR: getting or parsing entry/media, HTTP code: ", e); - } finally { - method.releaseConnection(); - } - } - - /** - * Get workspace or null if collection is not associated with a workspace. - */ - public Workspace getWorkspace() { - return workspace; - } - - /** - * Determines if collection is writable. - */ - public boolean isWritable() { - return writable; - } - - /** - * Create new entry associated with collection, but do not save to server. - * @throws ProponoException if collecton is not writable. - */ - public ClientEntry createEntry() throws ProponoException { - if (!isWritable()) throw new ProponoException("Collection is not writable"); - return new ClientEntry(service, this); - } - - /** - * Create new media entry assocaited with collection, but do not save. - * server. Depending on the Atom server, you may or may not be able to - * persist the properties of the entry that is returned. - * @param title Title to used for uploaded file. - * @param slug String to be used in file-name of stored file - * @param contentType MIME content-type of file. - * @param bytes Data to be uploaded as byte array. - * @throws ProponoException if collecton is not writable - */ - public ClientMediaEntry createMediaEntry( - String title, String slug, String contentType, byte[] bytes) - throws ProponoException { - if (!isWritable()) throw new ProponoException("Collection is not writable"); - return new ClientMediaEntry(service, this, title, slug, contentType, bytes); - } - - /** - * Create new media entry assocaited with collection, but do not save. - * server. Depending on the Atom server, you may or may not be able to. - * persist the properties of the entry that is returned. - * @param title Title to used for uploaded file. - * @param slug String to be used in file-name of stored file - * @param contentType MIME content-type of file. - * @param is Data to be uploaded as InputStream. - * @throws ProponoException if collecton is not writable - */ - public ClientMediaEntry createMediaEntry( - String title, String slug, String contentType, InputStream is) - throws ProponoException { - if (!isWritable()) throw new ProponoException("Collection is not writable"); - return new ClientMediaEntry(service, this, title, slug, contentType, is); - } - - /** - * Save to collection a new entry that was created by a createEntry() - * or createMediaEntry() and save it to the server. - * @param entry Entry to be saved. - * @throws ProponoException on error, if collection is not writable or if entry is partial. - */ - public void addEntry(ClientEntry entry) throws ProponoException { - if (!isWritable()) throw new ProponoException("Collection is not writable"); - entry.addToCollection(this); - } - - protected void parseCollectionElement(Element element) throws ProponoException { - if (workspace == null) return; - - setHref(element.getAttribute("href").getValue()); - - Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); - if (titleElem != null) { - setTitle(titleElem.getText()); - if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { - setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); - } - } - - List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL); - if (acceptElems != null && acceptElems.size() > 0) { - for (Iterator it = acceptElems.iterator(); it.hasNext();) { - Element acceptElem = (Element)it.next(); - addAccept(acceptElem.getTextTrim()); - } - } - - // Loop to parse element to Categories objects - List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL); - for (Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) { - Element catsElem = (Element) catsIter.next(); - Categories cats = new ClientCategories(catsElem, this); - addCategories(cats); - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/ClientEntry.java b/src/main/java/com/sun/syndication/propono/atom/client/ClientEntry.java deleted file mode 100644 index d22f303..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/ClientEntry.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.feed.atom.Content; -import com.sun.syndication.feed.atom.Link; -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.io.impl.Atom10Generator; -import com.sun.syndication.io.impl.Atom10Parser; -import com.sun.syndication.propono.utils.ProponoException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringWriter; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.sun.syndication.propono.utils.Utilities; -import java.util.ArrayList; -import java.util.List; -import org.apache.commons.beanutils.BeanUtils; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.methods.PostMethod; - -/** - * Client implementation of Atom entry, extends ROME Entry to add methods for - * easily getting/setting content, updating and removing the entry from the server. - */ -public class ClientEntry extends Entry { - private static final Log logger = LogFactory.getLog(ClientEntry.class); - - boolean partial = false; - - private ClientAtomService service = null; - private ClientCollection collection = null; - - public ClientEntry(ClientAtomService service, ClientCollection collection) { - super(); - this.service = service; - this.collection = collection; - } - - public ClientEntry(ClientAtomService service, ClientCollection collection, - Entry entry, boolean partial) throws ProponoException { - super(); - this.service = service; - this.collection = collection; - this.partial = partial; - try { - BeanUtils.copyProperties(this, entry); - } catch (Exception e) { - throw new ProponoException("ERROR: copying fields from ROME entry", e); - } - } - - /** - * Set content of entry. - * @param contentString content string. - * @param type Must be "text" for plain text, "html" for escaped HTML, - * "xhtml" for XHTML or a valid MIME content-type. - */ - public void setContent(String contentString, String type) { - Content newContent = new Content(); - newContent.setType(type == null ? Content.HTML : type); - newContent.setValue(contentString); - ArrayList contents = new ArrayList(); - contents.add(newContent); - setContents(contents); - } - - /** - * Convenience method to set first content object in content collection. - * Atom 1.0 allows only one content element per entry. - */ - public void setContent(Content c) { - ArrayList contents = new ArrayList(); - contents.add(c); - setContents(contents); - } - - /** - * Convenience method to get first content object in content collection. - * Atom 1.0 allows only one content element per entry. - */ - public Content getContent() { - if (getContents() != null && getContents().size() > 0) { - Content c = (Content)getContents().get(0); - return c; - } - return null; - } - - /** - * Determines if entries are equal based on edit URI. - */ - public boolean equals(Object o) { - if (o instanceof ClientEntry) { - ClientEntry other = (ClientEntry)o; - if (other.getEditURI() != null && getEditURI() != null) { - return other.getEditURI().equals(getEditURI()); - } - } - return false; - } - - /** - * Update entry by posting new representation of entry to server. - * Note that you should not attempt to update entries that you get from - * iterating over a collection they may be "partial" entries. If you want - * to update an entry, you must get it via one of the getEntry() - * methods in - * {@link com.sun.syndication.propono.atom.common.Collection} or - * {@link com.sun.syndication.propono.atom.common.AtomService}. - * @throws ProponoException If entry is a "partial" entry. - */ - public void update() throws ProponoException { - if (partial) throw new ProponoException("ERROR: attempt to update partial entry"); - EntityEnclosingMethod method = new PutMethod(getEditURI()); - addAuthentication(method); - StringWriter sw = new StringWriter(); - int code = -1; - try { - Atom10Generator.serializeEntry(this, sw); - method.setRequestEntity(new StringRequestEntity(sw.toString())); - method.setRequestHeader( - "Content-type", "application/atom+xml; charset=utf-8"); - getHttpClient().executeMethod(method); - InputStream is = method.getResponseBodyAsStream(); - if (method.getStatusCode() != 200 && method.getStatusCode() != 201) { - throw new ProponoException( - "ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is)); - } - - } catch (Exception e) { - String msg = "ERROR: updating entry, HTTP code: " + code; - logger.debug(msg, e); - throw new ProponoException(msg, e); - } finally { - method.releaseConnection(); - } - } - - /** - * Remove entry from server. - */ - public void remove() throws ProponoException { - if (getEditURI() == null) { - throw new ProponoException("ERROR: cannot delete unsaved entry"); - } - DeleteMethod method = new DeleteMethod(getEditURI()); - addAuthentication(method); - try { - getHttpClient().executeMethod(method); - } catch (IOException ex) { - throw new ProponoException("ERROR: removing entry, HTTP code", ex); - } finally { - method.releaseConnection(); - } - } - - void setCollection(ClientCollection collection) { - this.collection = collection; - } - - ClientCollection getCollection() { - return collection; - } - - /** - * Get the URI that can be used to edit the entry via HTTP PUT or DELETE. - */ - public String getEditURI() { - for (int i=0; i 0) { - Content c = (Content)getContents().get(0); - if (c.getSrc() != null) { - return getResourceAsStream(); - } else if (inputStream != null) { - return inputStream; - } else if (bytes != null) { - return new ByteArrayInputStream(bytes); - } else { - throw new ProponoException("ERROR: no src URI or binary data to return"); - } - } - else { - throw new ProponoException("ERROR: no content found in entry"); - } - } - - private InputStream getResourceAsStream() throws ProponoException { - if (getEditURI() == null) { - throw new ProponoException("ERROR: not yet saved to server"); - } - GetMethod method = new GetMethod(((Content)getContents()).getSrc()); - try { - getCollection().getHttpClient().executeMethod(method); - if (method.getStatusCode() != 200) { - throw new ProponoException("ERROR HTTP status=" + method.getStatusCode()); - } - return method.getResponseBodyAsStream(); - } catch (IOException e) { - throw new ProponoException("ERROR: getting media entry", e); - } - } - - /** - * Update entry on server. - */ - public void update() throws ProponoException { - if (partial) throw new ProponoException("ERROR: attempt to update partial entry"); - EntityEnclosingMethod method = null; - Content updateContent = (Content)getContents().get(0); - try { - if (getMediaLinkURI() != null && getBytes() != null) { - // existing media entry and new file, so PUT file to edit-media URI - method = new PutMethod(getMediaLinkURI()); - if (inputStream != null) { - method.setRequestEntity(new InputStreamRequestEntity(inputStream)); - } else { - method.setRequestEntity(new InputStreamRequestEntity(new ByteArrayInputStream(getBytes()))); - } - - method.setRequestHeader("Content-type", updateContent.getType()); - } - else if (getEditURI() != null) { - // existing media entry and NO new file, so PUT entry to edit URI - method = new PutMethod(getEditURI()); - StringWriter sw = new StringWriter(); - Atom10Generator.serializeEntry(this, sw); - method.setRequestEntity(new StringRequestEntity(sw.toString())); - method.setRequestHeader( - "Content-type", "application/atom+xml; charset=utf8"); - } else { - throw new ProponoException("ERROR: media entry has no edit URI or media-link URI"); - } - this.getCollection().addAuthentication(method); - method.addRequestHeader("Title", getTitle()); - getCollection().getHttpClient().executeMethod(method); - if (inputStream != null) inputStream.close(); - InputStream is = method.getResponseBodyAsStream(); - if (method.getStatusCode() != 200 && method.getStatusCode() != 201) { - throw new ProponoException( - "ERROR HTTP status=" + method.getStatusCode() + " : " + Utilities.streamToString(is)); - } - - } catch (Exception e) { - throw new ProponoException("ERROR: saving media entry"); - } - if (method.getStatusCode() != 201) { - throw new ProponoException("ERROR HTTP status=" + method.getStatusCode()); - } - } - - /** Package access, to be called by DefaultClientCollection */ - void addToCollection(ClientCollection col) throws ProponoException { - setCollection(col); - EntityEnclosingMethod method = new PostMethod(col.getHrefResolved()); - getCollection().addAuthentication(method); - StringWriter sw = new StringWriter(); - boolean error = false; - try { - Content c = (Content)getContents().get(0); - if (inputStream != null) { - method.setRequestEntity(new InputStreamRequestEntity(inputStream)); - } else { - method.setRequestEntity(new InputStreamRequestEntity(new ByteArrayInputStream(getBytes()))); - } - method.setRequestHeader("Content-type", c.getType()); - method.setRequestHeader("Title", getTitle()); - method.setRequestHeader("Slug", getSlug()); - getCollection().getHttpClient().executeMethod(method); - if (inputStream != null) inputStream.close(); - InputStream is = method.getResponseBodyAsStream(); - if (method.getStatusCode() == 200 || method.getStatusCode() == 201) { - Entry romeEntry = Atom10Parser.parseEntry( - new InputStreamReader(is), col.getHrefResolved()); - BeanUtils.copyProperties(this, romeEntry); - - } else { - throw new ProponoException( - "ERROR HTTP status-code=" + method.getStatusCode() - + " status-line: " + method.getStatusLine()); - } - } catch (IOException ie) { - throw new ProponoException("ERROR: saving media entry", ie); - } catch (JDOMException je) { - throw new ProponoException("ERROR: saving media entry", je); - } catch (FeedException fe) { - throw new ProponoException("ERROR: saving media entry", fe); - } catch (IllegalAccessException ae) { - throw new ProponoException("ERROR: saving media entry", ae); - } catch (InvocationTargetException te) { - throw new ProponoException("ERROR: saving media entry", te); - } - Header locationHeader = method.getResponseHeader("Location"); - if (locationHeader == null) { - logger.warn("WARNING added entry, but no location header returned"); - } else if (getEditURI() == null) { - List links = getOtherLinks(); - Link link = new Link(); - link.setHref(locationHeader.getValue()); - link.setRel("edit"); - links.add(link); - setOtherLinks(links); - } - } - - /** Set string to be used in file name of new media resource on server. */ - public String getSlug() { - return slug; - } - - /** Get string to be used in file name of new media resource on server. */ - public void setSlug(String slug) { - this.slug = slug; - } - -} - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/com/sun/syndication/propono/atom/client/ClientWorkspace.java b/src/main/java/com/sun/syndication/propono/atom/client/ClientWorkspace.java deleted file mode 100644 index 6377662..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/ClientWorkspace.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.atom.common.Workspace; -import com.sun.syndication.propono.atom.common.Workspace; -import com.sun.syndication.propono.utils.ProponoException; -import java.util.Iterator; -import java.util.List; -import org.jdom.Element; - - -/** - * Represents Atom protocol workspace on client-side. - * It extends the common - * {@link com.sun.syndication.propono.atom.common.Workspace} - * to return - * {@link com.sun.syndication.propono.atom.client.ClientCollection} - * objects instead of common - * {@link com.sun.syndication.propono.atom.common.Collection}s. - */ -public class ClientWorkspace extends Workspace { - private ClientAtomService atomService = null; - - ClientWorkspace(Element e, ClientAtomService atomService, String baseURI) throws ProponoException { - super("dummy", "dummy"); - this.atomService = atomService; - parseWorkspaceElement(e, baseURI); - } - - /** - * Package access to parent service. - */ - ClientAtomService getAtomService() { - return atomService; - } - - /** Deserialize a Atom workspace XML element into an object */ - protected void parseWorkspaceElement(Element element, String baseURI) throws ProponoException { - Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); - setTitle(titleElem.getText()); - if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { - setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); - } - List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL); - Iterator iter = collections.iterator(); - while (iter.hasNext()) { - Element e = (Element) iter.next(); - addCollection(new ClientCollection(e, this, baseURI)); - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/EntryIterator.java b/src/main/java/com/sun/syndication/propono/atom/client/EntryIterator.java deleted file mode 100644 index 5014d8f..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/EntryIterator.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.client; - -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.WireFeedInput; -import com.sun.syndication.propono.utils.ProponoException; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jdom.Document; -import org.jdom.input.SAXBuilder; - - -/** - * Enables iteration over entries in Atom protocol collection. - */ -public class EntryIterator implements Iterator { - static final Log logger = LogFactory.getLog(EntryIterator.class); - private final ClientCollection collection; - - int maxEntries = 20; - int offset = 0; - Iterator members = null; - Feed col = null; - String collectionURI; - String nextURI; - - EntryIterator(ClientCollection collection) throws ProponoException { - this.collection = collection; - collectionURI = collection.getHrefResolved(); - nextURI = collectionURI; - getNextEntries(); - } - - /** - * Returns true if more entries are available. - */ - public boolean hasNext() { - if (!members.hasNext()) { - try { - getNextEntries(); - } catch (Exception ignored) { - logger.error("ERROR getting next entries", ignored); - } - } - return members.hasNext(); - } - - /** - * Get next entry in collection. - */ - public Object next() { - if (hasNext()) { - Entry romeEntry = (Entry)members.next(); - try { - if (!romeEntry.isMediaEntry()) { - return new ClientEntry(null, collection, romeEntry, true); - } else { - return new ClientMediaEntry(null, collection, romeEntry, true); - } - } catch (ProponoException e) { - throw new RuntimeException("Unexpected exception creating ClientEntry or ClientMedia", e); - } - } - throw new NoSuchElementException(); - } - - /** - * Remove entry is not implemented. - */ - public void remove() { - // optional method, not implemented - } - - private void getNextEntries() throws ProponoException { - if (nextURI == null) return; - GetMethod colGet = new GetMethod( collection.getHrefResolved(nextURI) ); - collection.addAuthentication(colGet); - try { - collection.getHttpClient().executeMethod(colGet); - SAXBuilder builder = new SAXBuilder(); - Document doc = builder.build(colGet.getResponseBodyAsStream()); - WireFeedInput feedInput = new WireFeedInput(); - col = (Feed) feedInput.build(doc); - } catch (Exception e) { - throw new ProponoException("ERROR: fetching or parsing next entries, HTTP code: " + (colGet != null ? colGet.getStatusCode() : -1), e); - } finally { - colGet.releaseConnection(); - } - members = col.getEntries().iterator(); - offset += col.getEntries().size(); - - nextURI = null; - List altLinks = col.getOtherLinks(); - if (altLinks != null) { - Iterator iter = altLinks.iterator(); - while (iter.hasNext()) { - Link link = (Link)iter.next(); - if ("next".equals(link.getRel())) { - nextURI = link.getHref(); - } - } - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/GDataAuthStrategy.java b/src/main/java/com/sun/syndication/propono/atom/client/GDataAuthStrategy.java deleted file mode 100644 index 987db9f..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/GDataAuthStrategy.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2009 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.utils.ProponoException; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.httpclient.methods.PostMethod; - - -public class GDataAuthStrategy implements AuthStrategy { - private String email; - private String password; - private String service; - private String authToken; - - public GDataAuthStrategy(String email, String password, String service) throws ProponoException { - this.email = email; - this.password = password; - this.service = service; - init(); - } - - private void init() throws ProponoException { - try { - HttpClient httpClient = new HttpClient(); - PostMethod method = new PostMethod("https://www.google.com/accounts/ClientLogin"); - NameValuePair[] data = { - new NameValuePair("Email", email), - new NameValuePair("Passwd", password), - new NameValuePair("accountType", "GOOGLE"), - new NameValuePair("service", service), - new NameValuePair("source", "ROME Propono Atompub Client") - }; - method.setRequestBody(data); - httpClient.executeMethod(method); - - String responseBody = method.getResponseBodyAsString(); - int authIndex = responseBody.indexOf("Auth="); - - authToken = "GoogleLogin auth=" + responseBody.trim().substring(authIndex + 5); - - } catch (Throwable t) { - t.printStackTrace(); - throw new ProponoException("ERROR obtaining Google authentication string", t); - } - } - - public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { - httpClient.getParams().setAuthenticationPreemptive(true); - method.setRequestHeader("Authorization", authToken); - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/NoAuthStrategy.java b/src/main/java/com/sun/syndication/propono/atom/client/NoAuthStrategy.java deleted file mode 100644 index 68fb129..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/NoAuthStrategy.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2009 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.utils.ProponoException; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; - -/** - * No authentication - */ -public class NoAuthStrategy implements AuthStrategy { - - public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { - // no-op - } - -} diff --git a/src/main/java/com/sun/syndication/propono/atom/client/OAuthStrategy.java b/src/main/java/com/sun/syndication/propono/atom/client/OAuthStrategy.java deleted file mode 100644 index 56f3b0c..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/client/OAuthStrategy.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2009 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.atom.client; - -import com.sun.syndication.propono.utils.ProponoException; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import net.oauth.OAuth; -import net.oauth.OAuthAccessor; -import net.oauth.OAuthConsumer; -import net.oauth.OAuthMessage; -import net.oauth.OAuthServiceProvider; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.util.ParameterParser; - - -/** - * Strategy for using OAuth. - */ -public class OAuthStrategy implements AuthStrategy { - - private State state = State.UNAUTHORIZED; - - private enum State { - UNAUTHORIZED, // have not sent any requests - REQUEST_TOKEN, // have a request token - AUTHORIZED, // are authorized - ACCESS_TOKEN // have access token, ready to make calls - } - - private String username; - private String consumerKey; - private String consumerSecret; - private String keyType; - - private String reqUrl; - private String authzUrl; - private String accessUrl; - - private String nonce; - private long timestamp; - - private String requestToken = null; - private String accessToken = null; - private String tokenSecret = null; - - /** - * Create OAuth authentcation strategy and negotiate with services to - * obtain access token to be used in subsequent calls. - * - * @param username Username to be used in authentication - * @param key Consumer key - * @param secret Consumer secret - * @param keyType Key type (e.g. "HMAC-SHA1") - * @param reqUrl URL of request token service - * @param authzUrl URL of authorize service - * @param accessUrl URL of acess token service - * @throws ProponoException on any sort of initialization error - */ - public OAuthStrategy( - String username, String key, String secret, String keyType, - String reqUrl, String authzUrl, String accessUrl) throws ProponoException { - - this.username = username; - this.reqUrl = reqUrl; - this.authzUrl = authzUrl; - this.accessUrl = accessUrl; - this.consumerKey = key; - this.consumerSecret = secret; - this.keyType = keyType; - - this.nonce = UUID.randomUUID().toString(); - this.timestamp = (long)(new Date().getTime()/1000L); - - init(); - } - - private void init() throws ProponoException { - callOAuthUri(reqUrl); - callOAuthUri(authzUrl); - callOAuthUri(accessUrl); - } - - public void addAuthentication(HttpClient httpClient, HttpMethodBase method) throws ProponoException { - - if (state != State.ACCESS_TOKEN) { - throw new ProponoException("ERROR: authentication strategy failed init"); - } - - // add OAuth name/values to request query string - - // wish we didn't have to parse them apart first, ugh - List originalqlist = null; - if (method.getQueryString() != null) { - String qstring = method.getQueryString().trim(); - qstring = qstring.startsWith("?") ? qstring.substring(1) : qstring; - originalqlist = new ParameterParser().parse(qstring, '&'); - } else { - originalqlist = new ArrayList(); - } - - // put query string into hashmap form to please OAuth.net classes - Map params = new HashMap(); - for (Iterator it = originalqlist.iterator(); it.hasNext();) { - NameValuePair pair = (NameValuePair)it.next(); - params.put(pair.getName(), pair.getValue()); - } - - // add OAuth params to query string - params.put("xoauth_requestor_id", username); - params.put("oauth_consumer_key", consumerKey); - params.put("oauth_signature_method", keyType); - params.put("oauth_timestamp", Long.toString(timestamp)); - params.put("oauth_nonce", nonce); - params.put("oauth_token", accessToken); - params.put("oauth_token_secret", tokenSecret); - - // sign complete URI - String finalUri = null; - OAuthServiceProvider provider = - new OAuthServiceProvider(reqUrl, authzUrl, accessUrl); - OAuthConsumer consumer = - new OAuthConsumer(null, consumerKey, consumerSecret, provider); - OAuthAccessor accessor = new OAuthAccessor(consumer); - accessor.tokenSecret = tokenSecret; - OAuthMessage message; - try { - message = new OAuthMessage( - method.getName(), method.getURI().toString(), params.entrySet()); - message.sign(accessor); - - finalUri = OAuth.addParameters(message.URL, message.getParameters()); - - } catch (Exception ex) { - throw new ProponoException("ERROR: OAuth signing request", ex); - } - - // pull query string off and put it back onto method - method.setQueryString(finalUri.substring(finalUri.lastIndexOf("?"))); - } - - - private void callOAuthUri(String uri) throws ProponoException { - - final HttpClient httpClient = new HttpClient(); - - final HttpMethodBase method; - final String content; - - Map params = new HashMap(); - if (params == null) { - params = new HashMap(); - } - params.put("oauth_version", "1.0"); - if (username != null) { - params.put("xoauth_requestor_id", username); - } - params.put("oauth_consumer_key", consumerKey); - params.put("oauth_signature_method", keyType); - params.put("oauth_timestamp", Long.toString(timestamp)); - params.put("oauth_nonce", nonce); - params.put("oauth_callback", "none"); - - OAuthServiceProvider provider = - new OAuthServiceProvider(reqUrl, authzUrl, accessUrl); - OAuthConsumer consumer = - new OAuthConsumer(null, consumerKey, consumerSecret, provider); - OAuthAccessor accessor = new OAuthAccessor(consumer); - - if (state == State.UNAUTHORIZED) { - - try { - OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet()); - message.sign(accessor); - - String finalUri = OAuth.addParameters(message.URL, message.getParameters()); - method = new GetMethod(finalUri); - httpClient.executeMethod(method); - content = method.getResponseBodyAsString(); - - } catch (Exception e) { - throw new ProponoException("ERROR fetching request token", e); - } - - } else if (state == State.REQUEST_TOKEN) { - - try { - params.put("oauth_token", requestToken); - params.put("oauth_token_secret", tokenSecret); - accessor.tokenSecret = tokenSecret; - - OAuthMessage message = new OAuthMessage("POST", uri, params.entrySet()); - message.sign(accessor); - - String finalUri = OAuth.addParameters(message.URL, message.getParameters()); - method = new PostMethod(finalUri); - httpClient.executeMethod(method); - content = method.getResponseBodyAsString(); - - } catch (Exception e) { - throw new ProponoException("ERROR fetching request token", e); - } - - } else if (state == State.AUTHORIZED) { - - try { - params.put("oauth_token", accessToken); - params.put("oauth_token_secret", tokenSecret); - accessor.tokenSecret = tokenSecret; - - OAuthMessage message = new OAuthMessage("GET", uri, params.entrySet()); - message.sign(accessor); - - String finalUri = OAuth.addParameters(message.URL, message.getParameters()); - method = new GetMethod(finalUri); - httpClient.executeMethod(method); - content = method.getResponseBodyAsString(); - - } catch (Exception e) { - throw new ProponoException("ERROR fetching request token", e); - } - - } else { - method = null; - content = null; - return; - } - - - String token = null; - String secret = null; - - if (content != null) { - String[] settings = content.split("&"); - for (int i=0; i 1) { - if ("oauth_token".equals(setting[0])) { - token = setting[1]; - } else if ("oauth_token_secret".equals(setting[0])) { - secret = setting[1]; - } - } - } - } - - switch (state) { - - case UNAUTHORIZED: - if (token != null && secret != null) { - requestToken = token; - tokenSecret = secret; - state = State.REQUEST_TOKEN; - } else { - throw new ProponoException("ERROR: requestToken or tokenSecret is null"); - } - break; - - case REQUEST_TOKEN: - if (method.getStatusCode() == 200) { - state = State.AUTHORIZED; - } else { - throw new ProponoException("ERROR: authorization returned code: " + method.getStatusCode()); - } - break; - - case AUTHORIZED: - if (token != null && secret != null) { - accessToken = token; - tokenSecret = secret; - state = State.ACCESS_TOKEN; - } else { - throw new ProponoException("ERROR: accessToken or tokenSecret is null"); - } - break; - } - } -} - - diff --git a/src/main/java/com/sun/syndication/propono/atom/client/atomclient-diagram.gif b/src/main/java/com/sun/syndication/propono/atom/client/atomclient-diagram.gif deleted file mode 100644 index 21b109493156d9d46d41e44dc7c0e3a859a74389..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19120 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 elements - for (Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) { - Category cat = (Category) catIter.next(); - Element catElem = new Element("category", AtomService.ATOM_FORMAT); - catElem.setAttribute("term", cat.getTerm(), AtomService.ATOM_FORMAT); - if (cat.getScheme() != null) { // optional - catElem.setAttribute("scheme", cat.getScheme(), AtomService.ATOM_FORMAT); - } - if (cat.getLabel() != null) { // optional - catElem.setAttribute("label", cat.getLabel(), AtomService.ATOM_FORMAT); - } - catsElem.addContent(catElem); - } - } - return catsElem; - } - - protected void parseCategoriesElement(Element catsElem) { - if (catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL) != null) { - setHref(catsElem.getAttribute("href", AtomService.ATOM_PROTOCOL).getValue()); - } - if (catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL) != null) { - if ("yes".equals(catsElem.getAttribute("fixed", AtomService.ATOM_PROTOCOL).getValue())) { - setFixed(true); - } - } - if (catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL) != null) { - setScheme(catsElem.getAttribute("scheme", AtomService.ATOM_PROTOCOL).getValue()); - } - // Loop to parse elemenents to Category objects - List catElems = catsElem.getChildren("category", AtomService.ATOM_FORMAT); - for (Iterator catIter = catElems.iterator(); catIter.hasNext();) { - Element catElem = (Element) catIter.next(); - Category cat = new Category(); - cat.setTerm(catElem.getAttributeValue("term", AtomService.ATOM_FORMAT)); - cat.setLabel(catElem.getAttributeValue("label", AtomService.ATOM_FORMAT)); - cat.setScheme(catElem.getAttributeValue("scheme", AtomService.ATOM_FORMAT)); - addCategory(cat); - } - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/common/Collection.java b/src/main/java/com/sun/syndication/propono/atom/common/Collection.java deleted file mode 100644 index 0e4f5e7..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/Collection.java +++ /dev/null @@ -1,252 +0,0 @@ -/* -* 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 com.sun.syndication.propono.atom.common; - -import com.sun.syndication.io.impl.Atom10Parser; -import com.sun.syndication.propono.utils.ProponoException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.jdom.Element; - - -/** - * Models an Atom workspace collection. - */ -public class Collection { - - public static final String ENTRY_TYPE = "application/atom+xml;type=entry"; - - private Element collectionElement = null; - private String baseURI = null; - private String title = null; - private String titleType = null; // may be TEXT, HTML, XHTML - private List accepts = new ArrayList(); // of Strings - private String listTemplate = null; - private String href = null; - private List categories = new ArrayList(); // of Categories objects - - /** - * Collection MUST have title and href. - * @param title Title for collection - * @param titleType Content type of title (null for plain text) - * @param href Collection URI. - */ - public Collection(String title, String titleType, String href) { - this.title = title; - this.titleType = titleType; - this.href = href; - } - - /** Load self from XML element */ - public Collection(Element e) throws ProponoException { - this.collectionElement = e; - this.parseCollectionElement(e); - } - - /** Load self from XML element and base URI for resolving relative URIs */ - public Collection(Element e, String baseURI) throws ProponoException { - this.collectionElement = e; - this.baseURI = baseURI; - this.parseCollectionElement(e); - } - - /** - * List of content-type ranges accepted by collection. - */ - public List getAccepts() { - return accepts; - } - - public void addAccept(String accept) { - this.accepts.add(accept); - } - - public void setAccepts(List accepts) { - this.accepts = accepts; - } - - /** The URI of the collection */ - public String getHref() { - return href; - } - - /** - * Set URI of collection - */ - public void setHref(String href) { - this.href = href; - } - - /** Get resolved URI of the collection, or null if impossible to determine */ - public String getHrefResolved() { - if (Atom10Parser.isAbsoluteURI(href)) { - return href; - } else if (baseURI != null && collectionElement != null) { - int lastslash = baseURI.lastIndexOf("/"); - return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, href); - } - return null; - } - - /** Get resolved URI using collection's baseURI, or null if impossible to determine */ - public String getHrefResolved(String relativeUri) { - if (Atom10Parser.isAbsoluteURI(relativeUri)) { - return relativeUri; - } else if (baseURI != null && collectionElement != null) { - int lastslash = baseURI.lastIndexOf("/"); - return Atom10Parser.resolveURI(baseURI.substring(0, lastslash), collectionElement, relativeUri); - } - return null; - } - - /** Must have human readable title */ - public String getTitle() { - return title; - } - - /** - * Set title of collection. - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * Type of title ("text", "html" or "xhtml") - */ - public String getTitleType() { - return titleType; - } - - /** - * Type of title ("text", "html" or "xhtml") - */ - public void setTitleType(String titleType) { - this.titleType = titleType; - } - - /** Workspace can have multiple Categories objects */ - public void addCategories(Categories cats) { - categories.add(cats); - } - - /** - * Get categories allowed by collection. - * @return Collection of {@link com.sun.syndication.propono.atom.common.Categories} objects. - */ - public List getCategories() { - return categories; - } - - /** - * Returns true if contentType is accepted by collection. - */ - public boolean accepts(String ct) { - for (Iterator it = accepts.iterator(); it.hasNext();) { - String accept = (String)it.next(); - if (accept != null && accept.trim().equals("*/*")) return true; - String entryType = "application/atom+xml"; - boolean entry = entryType.equals(ct); - if (entry && null == accept) { - return true; - } else if (entry && "entry".equals(accept)) { - return true; - } else if (entry && entryType.equals(accept)) { - return true; - } else { - String[] rules = (String[])accepts.toArray(new String[accepts.size()]); - for (int i=0; i 0) { - rule = rule.substring(0, slashstar + 1); - if (ct.startsWith(rule)) return true; - } - } - } - } - return false; - } - - /** - * Serialize an AtomService.Collection into an XML element - */ - public Element collectionToElement() { - Collection collection = this; - Element element = new Element("collection", AtomService.ATOM_PROTOCOL); - element.setAttribute("href", collection.getHref()); - - Element titleElem = new Element("title", AtomService.ATOM_FORMAT); - titleElem.setText(collection.getTitle()); - if (collection.getTitleType() != null && !collection.getTitleType().equals("TEXT")) { - titleElem.setAttribute("type", collection.getTitleType(), AtomService.ATOM_FORMAT); - } - element.addContent(titleElem); - - // Loop to create elements - for (Iterator it = collection.getCategories().iterator(); it.hasNext();) { - Categories cats = (Categories)it.next(); - element.addContent(cats.categoriesToElement()); - } - - for (Iterator it = collection.getAccepts().iterator(); it.hasNext();) { - String range = (String)it.next(); - Element acceptElem = new Element("accept", AtomService.ATOM_PROTOCOL); - acceptElem.setText(range); - element.addContent(acceptElem); - } - - return element; - } - - /** Deserialize an Atom service collection XML element into an object */ - public Collection elementToCollection(Element element) throws ProponoException { - return new Collection(element); - } - - protected void parseCollectionElement(Element element) throws ProponoException { - setHref(element.getAttribute("href").getValue()); - - Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); - if (titleElem != null) { - setTitle(titleElem.getText()); - if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { - setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); - } - } - - List acceptElems = element.getChildren("accept", AtomService.ATOM_PROTOCOL); - if (acceptElems != null && acceptElems.size() > 0) { - for (Iterator it = acceptElems.iterator(); it.hasNext();) { - Element acceptElem = (Element)it.next(); - addAccept(acceptElem.getTextTrim()); - } - } - - // Loop to parse element to Categories objects - List catsElems = element.getChildren("categories", AtomService.ATOM_PROTOCOL); - for (Iterator catsIter = catsElems.iterator(); catsIter.hasNext();) { - Element catsElem = (Element) catsIter.next(); - Categories cats = new Categories(catsElem, baseURI); - addCategories(cats); - } - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/common/Workspace.java b/src/main/java/com/sun/syndication/propono/atom/common/Workspace.java deleted file mode 100644 index b15dbee..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/Workspace.java +++ /dev/null @@ -1,147 +0,0 @@ -/* -* 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 com.sun.syndication.propono.atom.common; - -import com.sun.syndication.propono.utils.ProponoException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.jdom.Element; - - -/** - * Models an Atom workspace. - */ -public class Workspace { - private String title = null; - private String titleType = null; // may be TEXT, HTML, XHTML - private List collections = new ArrayList(); - - /** - * Collection MUST have title. - * @param title Title for collection - * @param titleType Content type of title (null for plain text) - */ - public Workspace(String title, String titleType) { - this.title = title; - this.titleType = titleType; - } - - public Workspace(Element elem) throws ProponoException { - parseWorkspaceElement(elem); - } - - /** Iterate over collections in workspace */ - public List getCollections() { - return collections; - } - - /** Add new collection to workspace */ - public void addCollection(Collection col) { - collections.add(col); - } - - /** - * DefaultWorkspace must have a human readable title - */ - public String getTitle() { - return title; - } - - /** - * Set title of workspace. - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * Get title type ("text", "html", "xhtml" or MIME content-type) - */ - public String getTitleType() { - return titleType; - } - - /** - * Set title type ("text", "html", "xhtml" or MIME content-type) - */ - public void setTitleType(String titleType) { - this.titleType = titleType; - } - - /** - * Find collection by title and/or content-type. - * @param title Title or null to match all titles. - * @param contentType Content-type or null to match all content-types. - * @return First Collection that matches title and/or content-type. - */ - public Collection findCollection(String title, String contentType) { - for (Iterator it = collections.iterator(); it.hasNext();) { - Collection col = (Collection) it.next(); - if (title != null && col.accepts(contentType)) { - return col; - } else if (col.accepts(contentType)) { - return col; - } - } - return null; - } - - /** Deserialize a Atom workspace XML element into an object */ - public static Workspace elementToWorkspace(Element element) throws ProponoException { - return new Workspace(element); - } - - /** - * Serialize an AtomService.DefaultWorkspace object into an XML element - */ - public Element workspaceToElement() { - Workspace space = this; - - Element element = new Element("workspace", AtomService.ATOM_PROTOCOL); - - Element titleElem = new Element("title", AtomService.ATOM_FORMAT); - titleElem.setText(space.getTitle()); - if (space.getTitleType() != null && !space.getTitleType().equals("TEXT")) { - titleElem.setAttribute("type", space.getTitleType(), AtomService.ATOM_FORMAT); - } - element.addContent(titleElem); - - Iterator iter = space.getCollections().iterator(); - while (iter.hasNext()) { - Collection col = (Collection) iter.next(); - element.addContent(col.collectionToElement()); - } - return element; - } - - /** Deserialize a Atom workspace XML element into an object */ - protected void parseWorkspaceElement(Element element) throws ProponoException { - Element titleElem = element.getChild("title", AtomService.ATOM_FORMAT); - setTitle(titleElem.getText()); - if (titleElem.getAttribute("type", AtomService.ATOM_FORMAT) != null) { - setTitleType(titleElem.getAttribute("type", AtomService.ATOM_FORMAT).getValue()); - } - List collections = element.getChildren("collection", AtomService.ATOM_PROTOCOL); - Iterator iter = collections.iterator(); - while (iter.hasNext()) { - Element e = (Element) iter.next(); - addCollection(new Collection(e)); - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModule.java b/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModule.java deleted file mode 100644 index 495ee58..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModule.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.common.rome; - -import com.sun.syndication.feed.module.Module; -import java.util.Date; - -/** - * ROME Extension Module to Atom protocol extensions to Atom format. - */ -public interface AppModule extends Module { - public static final String URI = "http://www.w3.org/2007/app"; - - /** True if entry is a draft */ - public Boolean getDraft(); - - /** Set to true if entry is a draft */ - public void setDraft(Boolean draft); - - /** Time of last edit */ - public Date getEdited(); - - /** Set time of last edit */ - public void setEdited(Date edited); -} diff --git a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleGenerator.java b/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleGenerator.java deleted file mode 100644 index c182609..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleGenerator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.common.rome; - -import com.sun.syndication.io.impl.DateParser; -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; -import java.text.SimpleDateFormat; -import java.util.Locale; -import java.util.TimeZone; - -/** - * Creates JDOM representation for APP Extension Module. - */ -public class AppModuleGenerator implements ModuleGenerator { - private static final Namespace APP_NS = - Namespace.getNamespace("app", AppModule.URI); - - public String getNamespaceUri() { - return AppModule.URI; - } - - private static final Set NAMESPACES; - - static { - Set nss = new HashSet(); - nss.add(APP_NS); - NAMESPACES = Collections.unmodifiableSet(nss); - } - - /** Get namespaces associated with this module */ - public Set getNamespaces() { - return NAMESPACES; - } - - /** Generate JDOM element for module and add it to parent element */ - public void generate(Module module, Element parent) { - AppModule m = (AppModule)module; - - if (m.getDraft() != null) { - String draft = m.getDraft().booleanValue() ? "yes" : "no"; - Element control = new Element("control", APP_NS); - control.addContent(generateSimpleElement("draft", draft)); - parent.addContent(control); - } - if (m.getEdited() != null) { - Element edited = new Element("edited", APP_NS); - // Inclulde millis in date/time - SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); - dateFormater.setTimeZone(TimeZone.getTimeZone("GMT")); - edited.addContent(dateFormater.format(m.getEdited())); - parent.addContent(edited); - } - } - - private Element generateSimpleElement(String name, String value) { - Element element = new Element(name, APP_NS); - element.addContent(value); - return element; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleImpl.java b/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleImpl.java deleted file mode 100644 index e6485a5..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleImpl.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * Copyright 2011 The ROME Teams - * - * 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 com.sun.syndication.propono.atom.common.rome; - -import com.sun.syndication.feed.CopyFrom; -import com.sun.syndication.feed.module.ModuleImpl; -import java.util.Date; - -/** - * Bean representation of APP module. - */ -public class AppModuleImpl extends ModuleImpl implements AppModule { - private boolean draft = false; - private Date edited = null; - - public AppModuleImpl() { - super(AppModule.class, AppModule.URI); - } - - /** True if entry is draft */ - public Boolean getDraft() { - return draft ? Boolean.TRUE : Boolean.FALSE; - } - - /** Set to true if entry is draft */ - public void setDraft(Boolean draft) { - this.draft = draft.booleanValue(); - } - - /** Time of last edit */ - public Date getEdited() { - return edited; - } - - /** Set time of last edit */ - public void setEdited(Date edited) { - this.edited = edited; - } - - /** Get interface class of module */ - public Class getInterface() { - return AppModule.class; - } - - /** Copy from other module */ - public void copyFrom(CopyFrom obj) { - AppModule m = (AppModule)obj; - setDraft(m.getDraft()); - setEdited(m.getEdited()); - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleParser.java b/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleParser.java deleted file mode 100644 index 13b34c4..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/common/rome/AppModuleParser.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.common.rome; - -import com.sun.syndication.io.impl.DateParser; -import org.jdom.Element; -import org.jdom.Namespace; - -import com.sun.syndication.feed.module.Module; -import com.sun.syndication.io.ModuleParser; - -/** - * Parses APP module information from a JDOM element and into - * AppModule form. - */ -public class AppModuleParser implements ModuleParser { - - /** Get URI of module namespace */ - public String getNamespaceUri() { - return AppModule.URI; - } - - /** Get namespace of module */ - public Namespace getContentNamespace() { - return Namespace.getNamespace(AppModule.URI); - } - - /** Parse JDOM element into module */ - public Module parse(Element elem) { - boolean foundSomething = false; - AppModule m = new AppModuleImpl(); - Element control = elem.getChild("control", getContentNamespace()); - if (control != null) { - Element draftElem = control.getChild("draft", getContentNamespace()); - if (draftElem != null) { - if ("yes".equals(draftElem.getText())) m.setDraft(Boolean.TRUE); - if ("no".equals(draftElem.getText())) m.setDraft(Boolean.FALSE); - } - } - Element edited = elem.getChild("edited", getContentNamespace()); - if (edited != null) { - try { - m.setEdited(DateParser.parseW3CDateTime(edited.getTextTrim())); - } catch (Exception ignored) {} - } - return m; - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomException.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomException.java deleted file mode 100644 index 93a8543..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomException.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.server; - -import javax.servlet.http.HttpServletResponse; - - -/** - * Exception thrown by {@link com.sun.syndication.propono.atom.server.AtomHandler} - * and extended by other Propono Atom exception classes. - */ -public class AtomException extends Exception { - /** Construct new exception */ - public AtomException() { - super(); - } - /** Construct new exception with message */ - public AtomException(String msg) { - super(msg); - } - /** Contruct new exception with message and wrapping existing exception */ - public AtomException(String msg, Throwable t) { - super(msg, t); - } - /** Construct new exception to wrap existing one. */ - public AtomException(Throwable t) { - super(t); - } - /* Get HTTP status code associated with exception (HTTP 500 server error) */ - /** - * Get HTTP status associated with exception. - */ - public int getStatus() { - return HttpServletResponse.SC_INTERNAL_SERVER_ERROR; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomHandler.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomHandler.java deleted file mode 100644 index 8561073..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomHandler.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.server; - -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.feed.atom.Feed; -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.atom.common.Categories; - -/** - * Interface for handling single Atom protocol requests. - * - *

To create your own Atom protocol implementation you must implement this - * interface and create a concrete sub-class of - * {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} - * which is capable of instantiating it.

- */ -public interface AtomHandler -{ - /** - * Get username of authenticated user. Return the username of the - * authenticated user - */ - public String getAuthenticatedUsername(); - - /** - * Return - * {@link com.sun.syndication.propono.atom.common.AtomService} - * object that contains the - * {@link com.sun.syndication.propono.atom.common.Workspace} objects - * available to the currently authenticated user and within those the - * {@link com.sun.syndication.propono.atom.common.Collection} avalaible. - */ - public AtomService getAtomService(AtomRequest req) throws AtomException; - - /** - * Get categories, a list of Categories objects - */ - public Categories getCategories(AtomRequest req) throws AtomException; - - /** - * Return collection or portion of collection specified by request. - * @param req Details of HTTP request - */ - public Feed getCollection(AtomRequest req) throws AtomException; - - /** - * Store new entry in collection specified by request and return - * representation of entry as it is stored on server. - * @param req Details of HTTP request - * @return Location URL of new entry - */ - public Entry postEntry(AtomRequest req, Entry entry) throws AtomException; - - /** - * Get entry specified by request. - * @param req Details of HTTP request - */ - public Entry getEntry(AtomRequest req) throws AtomException; - - /** - * Get media resource specified by request. - * @param req Details of HTTP request - */ - public AtomMediaResource getMediaResource(AtomRequest req) throws AtomException; - - /** - * Update entry specified by request and return new entry as represented - * on the server. - * @param req Details of HTTP request - */ - public void putEntry(AtomRequest req, Entry entry) throws AtomException; - - - /** - * Delete entry specified by request. - * @param req Details of HTTP request - */ - public void deleteEntry(AtomRequest req) throws AtomException; - - /** - * Store media data in collection specified by request, create an Atom - * media-link entry to store metadata for the new media file and return - * that entry to the caller. - * @param req Details of HTTP request - * @param entry New entry initialzied with only title and content type - * @return Location URL of new media entry - */ - public Entry postMedia(AtomRequest req, Entry entry) throws AtomException; - - /** - * Update the media file part of a media-link entry. - * @param req Details of HTTP request - */ - public void putMedia(AtomRequest req) throws AtomException; - - /** - * Return true if specified request represents URI of a Service Document. - * @param req Details of HTTP request - */ - public boolean isAtomServiceURI(AtomRequest req); - - /** - * Return true if specified request represents URI of a Categories Document. - * @param req Details of HTTP request - */ - public boolean isCategoriesURI(AtomRequest req); - - /** - * Return true if specified request represents URI of a collection. - * @param req Details of HTTP request - */ - public boolean isCollectionURI(AtomRequest req); - - /** - * Return true if specified request represents URI of an Atom entry. - * @param req Details of HTTP request - */ - public boolean isEntryURI(AtomRequest req); - - /** - * Return true if specified patrequesthinfo represents media-edit URI. - * @param req Details of HTTP request - */ - public boolean isMediaEditURI(AtomRequest req); -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomHandlerFactory.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomHandlerFactory.java deleted file mode 100644 index ca5fc55..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomHandlerFactory.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Defines a factory that enables the - * {@link com.sun.syndication.propono.atom.server.AtomServlet} to obtain an - * {@link com.sun.syndication.propono.atom.server.AtomHandler} that handles an Atom request. - * - *

To create your own Atom protocol implementation you must sub-class this - * class with your own factory that is capable of creating instances of your - * {@link com.sun.syndication.propono.atom.server.AtomHandler} impementation.

- */ -public abstract class AtomHandlerFactory { - - private static Log log = - LogFactory.getFactory().getInstance(AtomHandlerFactory.class); - - private static final String DEFAULT_PROPERTY_NAME = - "com.sun.syndication.propono.atom.server.AtomHandlerFactory"; - - private static final String FALLBACK_IMPL_NAME = - "com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandlerFactory"; - - /* - *

Protected constructor to prevent instantiation. - * Use {@link #newInstance()}.

- */ - protected AtomHandlerFactory() { - } - - /** - * Obtain a new instance of a AtomHandlerFactory. This static - * method creates a new factory instance. This method uses the following - * ordered lookup procedure to determine the AtomHandlerFactory - * implementation class to load: - *
    - *
  • - * Use the com.sun.syndication.propono.atom.server.AtomHandlerFactory - * system property. - *
  • - *
  • - * Use the properties file "/propono.properties" in the classpath. - * This configuration file is in standard java.util.Properties - * format and contains the fully qualified name of the implementation - * class with the key being the system property defined above. - * - * The propono.properties file is read only once by Propono and it's - * values are then cached for future use. If the file does not exist - * when the first attempt is made to read from it, no further attempts - * are made to check for its existence. It is not possible to change - * the value of any property in propono.properties after it has been - * read for the first time. - *
  • - *
  • - * If not available, to determine the classname. The Services API will look - * for a classname in the file: - * META-INF/services/com.sun.syndication.AtomHandlerFactory - * in jars available to the runtime. - *
  • - *
  • - * Platform default AtomHandlerFactory instance. - *
  • - *
- * - * Once an application has obtained a reference to a AtomHandlerFactory - * it can use the factory to configure and obtain parser instances. - * - * @return New instance of a AtomHandlerFactory - * - * @throws FactoryConfigurationError if the implementation is not available - * or cannot be instantiated. - */ - public static AtomHandlerFactory newInstance() { - try { - return (AtomHandlerFactory) - FactoryFinder.find(DEFAULT_PROPERTY_NAME, FALLBACK_IMPL_NAME); - } catch (FactoryFinder.ConfigurationError e) { - log.error("ERROR: finding factory", e); - throw new FactoryConfigurationError(e.getException(), e.getMessage()); - } - } - - /** - * Creates a new instance of a {@link com.sun.syndication.propono.atom.server.AtomHandler} - * using the currently configured parameters. - * - * @return A new instance of a AtomHandler. - * - * @throws AtomConfigurationException if a AtomHandler cannot be created - * which satisfies the configuration requested. - */ - public abstract AtomHandler newAtomHandler( - HttpServletRequest req, HttpServletResponse res); -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomMediaResource.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomMediaResource.java deleted file mode 100644 index b9c1882..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomMediaResource.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.util.Date; -import javax.activation.FileTypeMap; -import javax.activation.MimetypesFileTypeMap; - -/** - * Represents a media link entry. - */ -public class AtomMediaResource { - private String contentType = null; - private long contentLength = 0; - private InputStream inputStream = null; - private Date lastModified = null; - private static FileTypeMap map = null; - - static { - // TODO: figure out why PNG is missing from Java MIME types - map = FileTypeMap.getDefaultFileTypeMap(); - if (map instanceof MimetypesFileTypeMap) { - try { - ((MimetypesFileTypeMap)map).addMimeTypes("image/png png PNG"); - } catch (Exception ignored) {} - } - } - - public AtomMediaResource(File resource) throws FileNotFoundException { - contentType = map.getContentType(resource.getName()); - contentLength = resource.length(); - lastModified = new Date(resource.lastModified()); - inputStream = new FileInputStream(resource); - } - - public AtomMediaResource(String name, long length, Date lastModified, InputStream is) - throws FileNotFoundException { - this.contentType = map.getContentType(name); - this.contentLength = length; - this.lastModified = lastModified; - this.inputStream = is; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public long getContentLength() { - return contentLength; - } - - public void setContentLength(long contentLength) { - this.contentLength = contentLength; - } - - public InputStream getInputStream() { - return inputStream; - } - - public void setInputStream(InputStream inputStream) { - this.inputStream = inputStream; - } - - public Date getLastModified() { - return lastModified; - } - - public void setLastModified(Date lastModified) { - this.lastModified = lastModified; - } - - -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomNotAuthorizedException.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomNotAuthorizedException.java deleted file mode 100644 index 6278b76..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomNotAuthorizedException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.server; - -import javax.servlet.http.HttpServletResponse; - -/** - * Exception to be thrown by AtomHandler implementations in the - * case that a user is not authorized to access a resource. - */ -public class AtomNotAuthorizedException extends AtomException { - /** Construct new exception */ - public AtomNotAuthorizedException() { - super(); - } - /** Construct new exception with message */ - public AtomNotAuthorizedException(String msg) { - super(msg); - } - /** Construct new exception with message and root cause */ - public AtomNotAuthorizedException(String msg, Throwable t) { - super(msg, t); - } - /** Construct new exception to wrap root cause*/ - public AtomNotAuthorizedException(Throwable t) { - super(t); - } - /** Get HTTP status code of exception (HTTP 403 unauthorized) */ - public int getStatus() { - return HttpServletResponse.SC_UNAUTHORIZED; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomNotFoundException.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomNotFoundException.java deleted file mode 100644 index ad71a68..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomNotFoundException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.server; - -import javax.servlet.http.HttpServletResponse; - -/** - * Exception thrown by AtomHandler in that case a resource is not found. - */ -public class AtomNotFoundException extends AtomException { - /** Construct new exception */ - public AtomNotFoundException() { - super(); - } - /** Construct new exception with message */ - public AtomNotFoundException(String msg) { - super(msg); - } - /** Construct new exception with message and root cause */ - public AtomNotFoundException(String msg, Throwable t) { - super(msg, t); - } - /** Construct new exception with root cause */ - public AtomNotFoundException(Throwable t) { - super(t); - } - /** Get HTTP status code associated with exception (404 not found) */ - public int getStatus() { - return HttpServletResponse.SC_NOT_FOUND; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomRequest.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomRequest.java deleted file mode 100644 index dc1e70d..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomRequest.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. - * - * 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 com.sun.syndication.propono.atom.server; - -import java.io.IOException; -import java.io.InputStream; -import java.security.Principal; -import java.util.Enumeration; -import java.util.Map; - -/** - * Represents HTTP request to be processed by AtomHandler. - */ -public interface AtomRequest { - - /** - * Returns any extra path information associated with the URL the client - * sent when it made this request. - */ - public String getPathInfo(); - - /** - * Returns the query string that is contained in the request URL after - * the path. - */ - public String getQueryString(); - - /** - * Returns the login of the user making this request, if the user has - * been authenticated, or null if the user has not been authenticated. - */ - public String getRemoteUser(); - - /** - * Returns a boolean indicating whether the authenticated user is included - * in the specified logical "role". - */ - public boolean isUserInRole(String arg0); - - /** - * Returns a java.security.Principal object containing the name of the - * current authenticated user. - */ - public Principal getUserPrincipal(); - - /** - * Returns the part of this request's URL from the protocol name up to the - * query string in the first line of the HTTP request. - */ - public String getRequestURI(); - - /** - * Reconstructs the URL the client used to make the request. - */ - public StringBuffer getRequestURL(); - - /** - * Returns the length, in bytes, of the request body and made available by - * the input stream, or -1 if the length is not known. - */ - public int getContentLength(); - - /** - * Returns the MIME type of the body of the request, or null if the type - * is not known. */ - public String getContentType(); - - /** - * Returns the value of a request parameter as a String, or null if the - * parameter does not exist. - */ - public String getParameter(String arg0); - - /** - * Returns an Enumeration of String objects containing the names of the - * parameters contained in this request. - */ - public Enumeration getParameterNames(); - - /** - * Returns an array of String objects containing all of the values the - * given request parameter has, or null if the parameter does not exist. - */ - public String[] getParameterValues(String arg0); - - /** - * Returns a java.util.Map of the parameters of this request. - */ - public Map getParameterMap(); - - /** - * Retrieves the body of the request as binary data using a - * ServletInputStream. - */ - public InputStream getInputStream() throws IOException; - - /** - * Returns the value of the specified request header as a long value that - * represents a Date object. */ - public long getDateHeader(String arg0); - - /** - * Returns the value of the specified request header as a String. - */ - public String getHeader(String arg0); - - /** - * Returns all the values of the specified request header as an Enumeration - * of String objects. - */ - public Enumeration getHeaders(String arg0); - - /** - * Returns an enumeration of all the header names this request contains. - */ - public Enumeration getHeaderNames(); - - /** - * Returns the value of the specified request header as an int. - */ - public int getIntHeader(String arg0); -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomRequestImpl.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomRequestImpl.java deleted file mode 100644 index 8be7833..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomRequestImpl.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2007 Sun Microsystems, Inc. - * - * 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 com.sun.syndication.propono.atom.server; - -import java.io.IOException; -import java.io.InputStream; -import java.security.Principal; -import java.util.Enumeration; -import java.util.Map; -import javax.servlet.http.HttpServletRequest; - -/** - * Default request implementation. - */ -public class AtomRequestImpl implements AtomRequest { - private HttpServletRequest wrapped = null; - - public AtomRequestImpl(HttpServletRequest wrapped) { - this.wrapped = wrapped; - } - - public String getPathInfo() { - return wrapped.getPathInfo() != null ? wrapped.getPathInfo() : ""; - } - - public String getQueryString() { - return wrapped.getQueryString(); - } - - public String getRemoteUser() { - return wrapped.getRemoteUser(); - } - - public boolean isUserInRole(String arg0) { - return wrapped.isUserInRole(arg0); - } - - public Principal getUserPrincipal() { - return wrapped.getUserPrincipal(); - } - - public String getRequestURI() { - return wrapped.getRequestURI(); - } - - public StringBuffer getRequestURL() { - return wrapped.getRequestURL(); - } - - public int getContentLength() { - return wrapped.getContentLength(); - } - - public String getContentType() { - return wrapped.getContentType(); - } - - public String getParameter(String arg0) { - return wrapped.getParameter(arg0); - } - - public Enumeration getParameterNames() { - return wrapped.getParameterNames(); - } - - public String[] getParameterValues(String arg0) { - return wrapped.getParameterValues(arg0); - } - - public Map getParameterMap() { - return wrapped.getParameterMap(); - } - - public InputStream getInputStream() throws IOException { - return wrapped.getInputStream(); - } - - public long getDateHeader(String arg0) { - return wrapped.getDateHeader(arg0); - } - - public String getHeader(String arg0) { - return wrapped.getHeader(arg0); - } - - public Enumeration getHeaders(String arg0) { - return wrapped.getHeaders(arg0); - } - - public Enumeration getHeaderNames() { - return wrapped.getHeaderNames(); - } - - public int getIntHeader(String arg0) { - return wrapped.getIntHeader(arg0); - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/AtomServlet.java b/src/main/java/com/sun/syndication/propono/atom/server/AtomServlet.java deleted file mode 100644 index 83815ea..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/AtomServlet.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2007 Apache Software Foundation - * - * 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 com.sun.syndication.propono.atom.server; - -import com.sun.syndication.feed.atom.Content; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Writer; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.jdom.Document; -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.WireFeedOutput; -import com.sun.syndication.io.impl.Atom10Generator; -import com.sun.syndication.io.impl.Atom10Parser; -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.atom.common.Categories; -import com.sun.syndication.propono.utils.Utilities; -import java.io.BufferedReader; -import java.util.Collections; -import java.util.Iterator; -import javax.servlet.ServletConfig; - -/** - * Atom Servlet implements Atom protocol by calling an - * {@link com.sun.syndication.propono.atom.server.AtomHandler} - * implementation. This servlet takes care of parsing incoming XML into ROME - * Atom {@link com.sun.syndication.feed.atom.Entry} objects, passing those to the handler and serializing - * to the response the entries and feeds returned by the handler. - */ -public class AtomServlet extends HttpServlet { - - /** - * Get feed type support by Servlet, "atom_1.0" - */ - public static final String FEED_TYPE = "atom_1.0"; - private static String contextDirPath = null; - - private static Log log = - LogFactory.getFactory().getInstance(AtomServlet.class); - - static { - Atom10Parser.setResolveURIs(true); - } - - //----------------------------------------------------------------------------- - /** - * Create an Atom request handler. - * TODO: make AtomRequestHandler implementation configurable. - */ - private AtomHandler createAtomRequestHandler( - HttpServletRequest request, HttpServletResponse response) - throws ServletException { - AtomHandlerFactory ahf = AtomHandlerFactory.newInstance(); - return ahf.newAtomHandler(request, response); - } - - //----------------------------------------------------------------------------- - /** - * Handles an Atom GET by calling handler and writing results to response. - */ - protected void doGet(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - log.debug("Entering"); - AtomHandler handler = createAtomRequestHandler(req, res); - String userName = handler.getAuthenticatedUsername(); - if (userName != null) { - AtomRequest areq = new AtomRequestImpl(req); - try { - if (handler.isAtomServiceURI(areq)) { - // return an Atom Service document - AtomService service = handler.getAtomService(areq); - Document doc = service.serviceToDocument(); - res.setContentType("application/atomsvc+xml; charset=utf-8"); - 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.isCategoriesURI(areq)) { - Categories cats = handler.getCategories(areq); - res.setContentType("application/xml"); - Writer writer = res.getWriter(); - Document catsDoc = new Document(); - catsDoc.setRootElement(cats.categoriesToElement()); - XMLOutputter outputter = new XMLOutputter(); - outputter.output(catsDoc, writer); - writer.close(); - res.setStatus(HttpServletResponse.SC_OK); - } - else if (handler.isCollectionURI(areq)) { - // return a collection - Feed col = handler.getCollection(areq); - col.setFeedType(FEED_TYPE); - WireFeedOutput wireFeedOutput = new WireFeedOutput(); - Document feedDoc = wireFeedOutput.outputJDom(col); - res.setContentType("application/atom+xml; charset=utf-8"); - 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(areq)) { - // return an entry - Entry entry = handler.getEntry(areq); - if (entry != null) { - res.setContentType("application/atom+xml; type=entry; charset=utf-8"); - Writer writer = res.getWriter(); - Atom10Generator.serializeEntry(entry, writer); - writer.close(); - } else { - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - } - } - else if (handler.isMediaEditURI(areq)) { - AtomMediaResource entry = handler.getMediaResource(areq); - res.setContentType(entry.getContentType()); - res.setContentLength((int)entry.getContentLength()); - Utilities.copyInputToOutput(entry.getInputStream(), res.getOutputStream()); - res.getOutputStream().flush(); - res.getOutputStream().close(); - } - else { - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - } - } catch (AtomException ae) { - res.sendError(ae.getStatus(), ae.getMessage()); - log.debug("ERROR processing GET", ae); - } catch (Exception e) { - res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - log.debug("ERROR processing GET", e); - } - } else { - res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\""); - res.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - log.debug("Exiting"); - } - - //----------------------------------------------------------------------------- - /** - * 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 { - log.debug("Entering"); - AtomHandler handler = createAtomRequestHandler(req, res); - String userName = handler.getAuthenticatedUsername(); - if (userName != null) { - AtomRequest areq = new AtomRequestImpl(req); - try { - if (handler.isCollectionURI(areq)) { - - if (req.getContentType().startsWith("application/atom+xml")) { - - // parse incoming entry - Entry entry = Atom10Parser.parseEntry(new BufferedReader( - new InputStreamReader(req.getInputStream(), "UTF-8")), null); - - // call handler to post it - Entry newEntry = handler.postEntry(areq, entry); - - // set Location and Content-Location headers - for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) { - Link link = (Link) it.next(); - if ("edit".equals(link.getRel())) { - res.addHeader("Location", link.getHrefResolved()); - break; - } - } - for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) { - Link link = (Link) it.next(); - if ("alternate".equals(link.getRel())) { - res.addHeader("Content-Location", link.getHrefResolved()); - break; - } - } - - // write entry back out to response - res.setStatus(HttpServletResponse.SC_CREATED); - res.setContentType("application/atom+xml; type=entry; charset=utf-8"); - - Writer writer = res.getWriter(); - Atom10Generator.serializeEntry(newEntry, writer); - writer.close(); - - } else if (req.getContentType() != null) { - - // get incoming title and slug from HTTP header - String title = areq.getHeader("Title"); - - // create new entry for resource, set title and type - Entry resource = new Entry(); - resource.setTitle(title); - Content content = new Content(); - content.setType(areq.getContentType()); - resource.setContents(Collections.singletonList(content)); - - // hand input stream off to hander to post file - Entry newEntry = handler.postMedia(areq, resource); - - // set Location and Content-Location headers - for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) { - Link link = (Link) it.next(); - if ("edit".equals(link.getRel())) { - res.addHeader("Location", link.getHrefResolved()); - break; - } - } - for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) { - Link link = (Link) it.next(); - if ("alternate".equals(link.getRel())) { - res.addHeader("Content-Location", link.getHrefResolved()); - break; - } - } - - res.setStatus(HttpServletResponse.SC_CREATED); - res.setContentType("application/atom+xml; type=entry; charset=utf-8"); - - Writer writer = res.getWriter(); - Atom10Generator.serializeEntry(newEntry, writer); - writer.close(); - - } else { - res.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, - "No content-type specified in request"); - } - - } else { - res.sendError(HttpServletResponse.SC_NOT_FOUND, - "Invalid collection specified in request"); - } - } catch (AtomException ae) { - res.sendError(ae.getStatus(), ae.getMessage()); - log.debug("ERROR processing POST", ae); - } catch (Exception e) { - res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - log.debug("ERROR processing POST", e); - } - } else { - res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\""); - res.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } - log.debug("Exiting"); - } - - //----------------------------------------------------------------------------- - /** - * 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 { - log.debug("Entering"); - AtomHandler handler = createAtomRequestHandler(req, res); - String userName = handler.getAuthenticatedUsername(); - if (userName != null) { - AtomRequest areq = new AtomRequestImpl(req); - try { - if (handler.isEntryURI(areq)) { - - // parse incoming entry - Entry unsavedEntry = Atom10Parser.parseEntry(new BufferedReader( - new InputStreamReader(req.getInputStream(), "UTF-8")), null); - - // call handler to put entry - handler.putEntry(areq, unsavedEntry); - - res.setStatus(HttpServletResponse.SC_OK); - - } else if (handler.isMediaEditURI(areq)) { - - // hand input stream to handler - handler.putMedia(areq); - - res.setStatus(HttpServletResponse.SC_OK); - - } else { - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - } - } catch (AtomException ae) { - res.sendError(ae.getStatus(), ae.getMessage()); - log.debug("ERROR processing PUT", ae); - } catch (Exception e) { - res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - log.debug("ERROR processing PUT", e); - } - } else { - res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\""); - // Wanted to use sendError() here but Tomcat sends 403 forbidden - // when I do that, so sticking with setStatus() for time being. - res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - log.debug("Exiting"); - } - - //----------------------------------------------------------------------------- - /** - * Handle Atom DELETE by calling appropriate handler. - */ - protected void doDelete(HttpServletRequest req, HttpServletResponse res) - throws ServletException, IOException { - log.debug("Entering"); - AtomHandler handler = createAtomRequestHandler(req, res); - String userName = handler.getAuthenticatedUsername(); - if (userName != null) { - AtomRequest areq = new AtomRequestImpl(req); - try { - if (handler.isEntryURI(areq)) { - handler.deleteEntry(areq); - res.setStatus(HttpServletResponse.SC_OK); - } - else { - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - } - } catch (AtomException ae) { - res.sendError(ae.getStatus(), ae.getMessage()); - log.debug("ERROR processing DELETE", ae); - } catch (Exception e) { - res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - log.debug("ERROR processing DELETE", e); - } - } else { - res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\""); - // Wanted to use sendError() here but Tomcat sends 403 forbidden - // when I do that, so sticking with setStatus() for time being. - res.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - } - log.debug("Exiting"); - } - - /** - * Initialize servlet. - */ - public void init( ServletConfig config ) throws ServletException { - super.init( config ); - contextDirPath = getServletContext().getRealPath("/"); - - } - - /** - * Get absolute path to Servlet context directory. - */ - public static String getContextDirPath() { - return contextDirPath; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/FactoryConfigurationError.java b/src/main/java/com/sun/syndication/propono/atom/server/FactoryConfigurationError.java deleted file mode 100644 index b35e0ff..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/FactoryConfigurationError.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server; - -/** - * Thrown when a problem with configuration with the - * {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} exists. - * This error will typically be thrown when the class of a parser factory - * specified in the system properties cannot be found or instantiated. - */ -public class FactoryConfigurationError extends Error { - - /** - * Exception that represents the error. - */ - private Exception exception; - - /** - * Create a new FactoryConfigurationError with no - * detail mesage. - */ - public FactoryConfigurationError() { - super(); - this.exception = null; - } - - /** - * Create a new FactoryConfigurationError with - * the String specified as an error message. - * - * @param msg The error message for the exception. - */ - public FactoryConfigurationError(String msg) { - super(msg); - this.exception = null; - } - - - /** - * Create a new FactoryConfigurationError with a - * given Exception base cause of the error. - * - * @param e The exception to be encapsulated in a - * FactoryConfigurationError. - */ - public FactoryConfigurationError(Exception e) { - super(e.toString()); - this.exception = e; - } - - /** - * Create a new FactoryConfigurationError with the - * given Exception base cause and detail message. - * - * @param e The exception to be encapsulated in a - * FactoryConfigurationError - * @param msg The detail message. - */ - public FactoryConfigurationError(Exception e, String msg) { - super(msg); - this.exception = e; - } - - - /** - * Return the message (if any) for this error . If there is no - * message for the exception and there is an encapsulated - * exception then the message of that exception, if it exists will be - * returned. Else the name of the encapsulated exception will be - * returned. - * - * @return The error message. - */ - public String getMessage() { - String message = super.getMessage(); - - if (message == null && exception != null) { - return exception.getMessage(); - } - - return message; - } - - /** - * Return the actual exception (if any) that caused this exception to - * be raised. - * - * @return The encapsulated exception, or null if there is none. - */ - public Exception getException() { - return exception; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/FactoryFinder.java b/src/main/java/com/sun/syndication/propono/atom/server/FactoryFinder.java deleted file mode 100644 index 67fbc6e..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/FactoryFinder.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server; - -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; - -/** - * Find {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} based on properties files. - */ -class FactoryFinder { - private static boolean debug = false; - static Properties cacheProps= new Properties(); - static SecuritySupport ss = new SecuritySupport() ; - static boolean firstTime = true; - - private static void dPrint(String msg) { - if (debug) { - System.err.println("Propono: " + msg); - } - } - - /** - * Create an instance of a class using the specified ClassLoader and - * optionally fall back to the current ClassLoader if not found. - * - * @param className Name of the concrete class corresponding to the - * service provider - * - * @param cl ClassLoader to use to load the class, null means to use - * the bootstrap ClassLoader - * - * @param doFallback true if the current ClassLoader should be tried as - * a fallback if the class is not found using cl - */ - private static Object newInstance( - String className, ClassLoader cl, boolean doFallback) - throws ConfigurationError { - - try { - Class providerClass; - if (cl == null) { - // If classloader is null Use the bootstrap ClassLoader. - // Thus Class.forName(String) will use the current - // ClassLoader which will be the bootstrap ClassLoader. - providerClass = Class.forName(className); - } else { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - cl = FactoryFinder.class.getClassLoader(); - providerClass = cl.loadClass(className); - } else { - throw x; - } - } - } - - Object instance = providerClass.newInstance(); - dPrint("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, x); - } - } - - /** - * Finds the implementation Class object in the specified order. Main - * entry point. - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * Package private so this code can be shared. - */ - static Object find(String factoryId, String fallbackClassName) - throws ConfigurationError { - - // Figure out which ClassLoader to use for loading the provider - // class. If there is a Context ClassLoader then use it. - - ClassLoader classLoader = ss.getContextClassLoader(); - - if (classLoader == null) { - // if we have no Context ClassLoader - // so use the current ClassLoader - classLoader = FactoryFinder.class.getClassLoader(); - } - - dPrint("find factoryId =" + factoryId); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if( systemProp!=null) { - dPrint("found system property, value=" + systemProp); - return newInstance(systemProp, classLoader, true ); - } - } catch (SecurityException se) { - //if first option fails due to any reason we should try next option in the - //look up algorithm. - } - - // try to read from /propono.properties - try { - String javah = ss.getSystemProperty("java.home"); - String configFile = "/propono.properties"; - String factoryClassName = null; - if(firstTime){ - synchronized(cacheProps){ - if (firstTime) { - try { - InputStream is = FactoryFinder.class.getResourceAsStream(configFile); - firstTime = false; - if (is != null) { - dPrint("Read properties file: " + configFile); - cacheProps.load(is); - } - } catch (Exception intentionallyIgnored) {} - } - } - } - factoryClassName = cacheProps.getProperty(factoryId); - - if(factoryClassName != null){ - dPrint("found in $java.home/propono.properties, value=" + factoryClassName); - return newInstance(factoryClassName, classLoader, true); - } - } catch(Exception ex) { - if( debug ) ex.printStackTrace(); - } - - // Try Jar Service Provider Mechanism - Object provider = findJarServiceProvider(factoryId); - if (provider != null) { - return provider; - } - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - dPrint("loaded from fallback value: " + fallbackClassName); - return newInstance(fallbackClassName, classLoader, true); - } - - /* - * Try to find provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError { - - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = ss.getContextClassLoader(); - if (cl != null) { - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - cl = FactoryFinder.class.getClassLoader(); - is = ss.getResourceAsStream(cl, serviceId); - } - } else { - // No Context ClassLoader, try the current - // ClassLoader - cl = FactoryFinder.class.getClassLoader(); - is = ss.getResourceAsStream(cl, serviceId); - } - - if (is == null) { - // No provider found - return null; - } - - dPrint("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // Read the service provider name in UTF-8 as specified in - // the jar spec. Unfortunately this fails in Microsoft - // VJ++, which does not implement the UTF-8 - // encoding. Theoretically, we should simply let it fail in - // that case, since the JVM is obviously broken if it - // doesn't support such a basic standard. But since there - // are still some users attempting to use VJ++ for - // development, we have dropped in a fallback which makes a - // second attempt using the platform's default encoding. In - // VJ++ this is apparently ASCII, which is a subset of - // UTF-8... and since the strings we'll be reading here are - // also primarily limited to the 7-bit ASCII range (at - // least, in English versions), this should work well - // enough to keep us on the air until we're ready to - // officially decommit from VJ++. [Edited comment from - // jkesselm] - BufferedReader rd; - try { - rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - rd.close(); - } catch (IOException x) { - // No provider found - return null; - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - dPrint("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // ClassLoader because we want to avoid the case where the - // resource file was found using one ClassLoader and the - // provider class was instantiated using a different one. - return newInstance(factoryClassName, cl, false); - } - - // No provider found - return null; - } - - static class ConfigurationError extends Error { - private Exception exception; - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } - - Exception getException() { - return exception; - } - } - -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/SecuritySupport.java b/src/main/java/com/sun/syndication/propono/atom/server/SecuritySupport.java deleted file mode 100644 index ab64b57..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/SecuritySupport.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server; - -import java.security.*; -import java.net.*; -import java.io.*; -import java.util.*; - -/** - * This class is duplicated for each subpackage, it is package private and - * therefore is not exposed as part of the public API. - */ -class SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - FileInputStream getFileInputStream(final File file) - throws FileNotFoundException { - try { - return (FileInputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws FileNotFoundException { - return new FileInputStream(file); - } - }); - } catch (PrivilegedActionException e) { - throw (FileNotFoundException)e.getException(); - } - } - - InputStream getResourceAsStream(final ClassLoader cl, - final String name) { - return (InputStream) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - }); - } - - boolean doesFileExist(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandler.java b/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandler.java deleted file mode 100644 index 018b8b2..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandler.java +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server.impl; - -import com.sun.syndication.propono.atom.server.AtomMediaResource; -import org.apache.commons.codec.binary.Base64; -import com.sun.syndication.propono.atom.server.AtomHandler; -import com.sun.syndication.propono.atom.server.AtomException; -import com.sun.syndication.propono.atom.server.AtomServlet; -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.feed.atom.Feed; -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.atom.common.Categories; -import com.sun.syndication.propono.atom.server.AtomRequest; -import java.io.File; -import java.util.StringTokenizer; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import javax.servlet.http.HttpServletRequest; -import org.apache.commons.lang.StringUtils; - - -/** - * File-based {@link com.sun.syndication.propono.atom.server.AtomHandler} - * implementation that stores entries and media-entries to disk. Implemented - * using {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomService}. - */ -public class FileBasedAtomHandler implements AtomHandler { - - private static Log log = - LogFactory.getFactory().getInstance(FileBasedAtomHandler.class); - - private static String fileStoreDir = null; - - private String userName = null; - private String atomProtocolURL = null; - private String contextURI = null; - private String uploadurl = null; - - private FileBasedAtomService service = null; - - /** - * Construct handler to handle one request. - * @param req Request to be handled. - */ - public FileBasedAtomHandler( HttpServletRequest req ) { - this(req, AtomServlet.getContextDirPath()); - } - - /** - * Contruct handler for one request, using specified file storage directory. - * @param req Request to be handled. - * @param uploaddir File storage upload dir. - */ - public FileBasedAtomHandler(HttpServletRequest req, String uploaddir) { - log.debug("ctor"); - - userName = authenticateBASIC(req); - - atomProtocolURL = req.getScheme() + "://" + req.getServerName() + ":" - + req.getServerPort() + req.getContextPath() + req.getServletPath(); - - contextURI = req.getScheme() + "://" + req.getServerName() + ":" - + req.getServerPort() + req.getContextPath(); - - try { - service = new FileBasedAtomService(userName, uploaddir, - contextURI, req.getContextPath(), req.getServletPath()); - } catch (Throwable t) { - throw new RuntimeException("ERROR creating FileBasedAtomService", t); - } - } - - /** - * Method used for validating user. Developers can overwrite this method - * and use credentials stored in Database or LDAP to confirm if the user is - * allowed to access this service. - * @param login user submitted login id - * @param password user submitted password - */ - public boolean validateUser(String login, String password) { - return true; - } - - /** - * Get username of authenticated user - * @return User name. - */ - public String getAuthenticatedUsername() { - // For now return userName as the login id entered for authorization - return userName; - } - - /** - * Get base URI of Atom protocol implementation. - * @return Base URI of Atom protocol implemenation. - */ - public String getAtomProtocolURL( ) { - if ( atomProtocolURL == null ) { - return "app"; - } else { - return atomProtocolURL; - } - } - - /** - * Return introspection document - * @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception. - * @return AtomService object with workspaces and collections. - */ - public AtomService getAtomService(AtomRequest areq) throws AtomException { - return service; - } - - /** - * Returns null because we use in-line categories. - * @throws com.sun.syndication.propono.atom.server.AtomException Unexpected exception. - * @return Categories object - */ - public Categories getCategories(AtomRequest areq) throws AtomException { - log.debug("getCollection"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - return (Categories)col.getCategories(true).get(0); - } - - /** - * Get collection specified by pathinfo. - * @param areq Details of HTTP request - * @return ROME feed representing collection. - * @throws com.sun.syndication.propono.atom.server.AtomException Invalid collection or other exception. - */ - public Feed getCollection(AtomRequest areq) throws AtomException { - log.debug("getCollection"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - return col.getFeedDocument(); - } - - /** - * Create a new entry specified by pathInfo and posted entry. We save the - * submitted Atom entry verbatim, but we do set the id and reset the update - * time. - * - * @param entry Entry to be added to collection. - * @param areq Details of HTTP request - * @throws com.sun.syndication.propono.atom.server.AtomException On invalid collection or other error. - * @return Entry as represented on server. - */ - public Entry postEntry(AtomRequest areq, Entry entry) throws AtomException { - log.debug("postEntry"); - - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - return col.addEntry(entry); - - } catch (Exception fe) { - fe.printStackTrace(); - throw new AtomException( fe ); - } - } - - /** - * Get entry specified by pathInfo. - * @param areq Details of HTTP request - * @throws com.sun.syndication.propono.atom.server.AtomException On invalid pathinfo or other error. - * @return ROME Entry object. - */ - public Entry getEntry(AtomRequest areq) throws AtomException { - log.debug("getEntry"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String fileName = pathInfo[2]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - return col.getEntry(fileName); - - } catch (Exception re) { - if (re instanceof AtomException) throw (AtomException)re; - throw new AtomException("ERROR: getting entry", re); - } - } - - /** - * Update entry specified by pathInfo and posted entry. - * - * @param entry - * @param areq Details of HTTP request - * @throws com.sun.syndication.propono.atom.server.AtomException - */ - public void putEntry(AtomRequest areq, Entry entry) throws AtomException { - log.debug("putEntry"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String fileName = pathInfo[2]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - col.updateEntry(entry, fileName); - - } catch ( Exception fe ) { - throw new AtomException( fe ); - } - } - - - /** - * Delete entry specified by pathInfo. - * @param areq Details of HTTP request - */ - public void deleteEntry(AtomRequest areq) throws AtomException { - log.debug("deleteEntry"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String fileName = pathInfo[2]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - col.deleteEntry(fileName); - - } catch (Exception e) { - String msg = "ERROR in atom.deleteResource"; - log.error(msg,e); - throw new AtomException(msg); - } - } - - - /** - * Store media data in collection specified by pathInfo, create an Atom - * media-link entry to store metadata for the new media file and return - * that entry to the caller. - * @param areq Details of HTTP request - * @param entry New entry initialzied with only title and content type - * @return Location URL of new media entry - */ - public Entry postMedia(AtomRequest areq, Entry entry) throws AtomException { - - // get incoming slug from HTTP header - String slug = areq.getHeader("Slug"); - - if (log.isDebugEnabled()) { - log.debug("postMedia - title: "+entry.getTitle()+" slug:"+slug); - } - - try { - File tempFile = null; - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - col.addMediaEntry(entry, slug, areq.getInputStream()); - - } catch (Exception e) { - e.printStackTrace(); - String msg = "ERROR reading posted file"; - log.error(msg,e); - throw new AtomException(msg, e); - } finally { - if (tempFile != null) tempFile.delete(); - } - - } catch (Exception re) { - throw new AtomException("ERROR: posting media"); - } - return entry; - } - - /** - * Update the media file part of a media-link entry. - * @param areq Details of HTTP request - * Assuming pathInfo of form /user-name/resource/name - */ - public void putMedia(AtomRequest areq) throws AtomException { - - log.debug("putMedia"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String fileName = pathInfo[3]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - col.updateMediaEntry(fileName, areq.getContentType(), areq.getInputStream()); - - } catch (Exception re) { - throw new AtomException("ERROR: posting media"); - } - } - - public AtomMediaResource getMediaResource(AtomRequest areq) throws AtomException { - log.debug("putMedia"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String fileName = pathInfo[3]; - FileBasedCollection col = service.findCollectionByHandle(handle, collection); - try { - return col.getMediaResource(fileName); - - } catch (Exception re) { - throw new AtomException("ERROR: posting media"); - } - } - - /** - * Return true if specified pathinfo represents URI of service doc. - */ - public boolean isAtomServiceURI(AtomRequest areq) { - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - if (pathInfo.length==0) return true; - return false; - } - - /** - * Return true if specified pathinfo represents URI of category doc. - */ - public boolean isCategoriesURI(AtomRequest areq) { - log.debug("isCategoriesDocumentURI"); - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - if (pathInfo.length == 3 && "categories".equals(pathInfo[2])) { - return true; - } - return false; - } - - /** - * Return true if specified pathinfo represents URI of a collection. - */ - public boolean isCollectionURI(AtomRequest areq) { - log.debug("isCollectionURI"); - // workspace/collection-plural - // if length is 2 and points to a valid collection then YES - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - if (pathInfo.length == 2) { - String handle = pathInfo[0]; - String collection = pathInfo[1]; - if (service.findCollectionByHandle(handle, collection) != null) { - return true; - } - } - return false; - - } - - /** - * Return true if specified pathinfo represents URI of an Atom entry. - */ - public boolean isEntryURI(AtomRequest areq) { - log.debug("isEntryURI"); - // workspace/collection-singular/fsid - // if length is 3 and points to a valid collection then YES - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - if (pathInfo.length == 3) { - String handle = pathInfo[0]; - String collection = pathInfo[1]; - if (service.findCollectionByHandle(handle, collection) != null) { - return true; - } - } - return false; - } - - /** - * Return true if specified pathinfo represents media-edit URI. - */ - public boolean isMediaEditURI(AtomRequest areq) { - log.debug("isMediaEditURI"); - // workspace/collection-singular/fsid/media/fsid - // if length is 4, points to a valid collection and fsid is mentioned twice then YES - String[] pathInfo = StringUtils.split(areq.getPathInfo(),"/"); - if (pathInfo.length == 4) { - String handle = pathInfo[0]; - String collection = pathInfo[1]; - String media = pathInfo[2]; - String fsid = pathInfo[3]; - if (service.findCollectionByHandle(handle, collection) != null && media.equals("media")) { - return true; - } - } - return false; - - } - - /** - * BASIC authentication. - */ - public String authenticateBASIC(HttpServletRequest request) { - log.debug("authenticateBASIC"); - 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); - password = userPass.substring(p+1); - - // Validate the User. - valid = validateUser( userID, password ); - } - } - } - } - } catch (Exception e) { - log.debug(e); - } - if (valid) { - //For now assume userID as userName - return userID; - } - return null; - } -} diff --git a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandlerFactory.java b/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandlerFactory.java deleted file mode 100644 index 74ba434..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomHandlerFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server.impl; - -import com.sun.syndication.propono.atom.server.AtomHandlerFactory; -import com.sun.syndication.propono.atom.server.AtomHandler; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * Extends {@link com.sun.syndication.propono.atom.server.AtomHandlerFactory} to create and return - * {@link com.sun.syndication.propono.atom.server.impl.FileBasedAtomHandler}. - */ -public class FileBasedAtomHandlerFactory extends AtomHandlerFactory { - - /** - * Create new AtomHandler. - */ - public AtomHandler newAtomHandler( - HttpServletRequest req, HttpServletResponse res ) { - return new FileBasedAtomHandler(req); - } -} - diff --git a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomService.java b/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomService.java deleted file mode 100644 index 9615a74..0000000 --- a/src/main/java/com/sun/syndication/propono/atom/server/impl/FileBasedAtomService.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2007 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 com.sun.syndication.propono.atom.server.impl; - -import com.sun.syndication.propono.atom.common.AtomService; -import com.sun.syndication.propono.utils.Utilities; -import java.io.InputStream; -import java.util.Map; -import java.util.Properties; -import java.util.TreeMap; - -/** - * File based Atom service. - * Supports one workspace per user. - * Collections in workspace are defined in /propono.properties, for example: - * - *
- *    # Define list of collections to be offered
- *    propono.atomserver.filebased.collections=entries,gifimages
- *
- *    # Defines 'entries' collection, accepts entries
- *    propono.atomserver.filebased.collection.entries.title=Entries
- *    propono.atomserver.filebased.collection.entries.singular=entry
- *    propono.atomserver.filebased.collection.entries.plural=entries
- *    propono.atomserver.filebased.collection.entries.accept=application/atom+xml;type=entry
- *    propono.atomserver.filebased.collection.entries.categories=general,category1,category2
- *
- *    # Defines 'gifimages' collection, accepts only GIF files
- *    propono.atomserver.filebased.collection.gifimages.title=GIF Images
- *    propono.atomserver.filebased.collection.gifimages.singular=gif
- *    propono.atomserver.filebased.collection.gifimages.plural=gifs
- *    propono.atomserver.filebased.collection.gifimages.accept=image/gif
- *    propono.atomserver.filebased.collection.gifimages.categories=general,category1,category2
- * 
- * - * If no such properties are found, then service will fall back to two - * collections: 'entries' for Atom entries and 'resources' for any content-type. - * - * - *

URI structure used for accessing collections and entries

- * - *

Collection feed (URI allows GET to get collection, POST to add to it)
- * [servlet-context-uri]/app/[workspace-handle]/[collection-plural] - *

- * - *

Collection entry (URI allows GET, PUT and DELETE)
- * [servlet-context-uri]/app/[workspace-handle]/[collection-singular]/[entryid] - *

- * - *

Collection entry media (URI allows GET, PUT and DELETE)
- * [servlet-context-uri]/app/[workspace-handle]/[collection-singular]/media/[entryid] - *

- * - *

Categories URI if not using inline categories (URI allows GET)
- * [servlet-context-uri]/app/[workspace-handle]/[collection-plural]/categories - *

- * - * - *

Directory structure used to store collections and entries

- * - *

Collection feed (kept constantly up to date)
- * [servlet-context-dir]/[workspace-handle]/[collection-plural]/feed.xml - *

- * - *

Collection entry (individual entries also stored as entry.xml files)
- * [servlet-context-dir]/[workspace-handle]/[collection-plural]/id/entry.xml - *

- * - *

Collection entry media (media file stored under entry directory)
- * [servlet-context-dir]/[workspace-handle]/[collection-plural]/id/media/id - *

- */ -public class FileBasedAtomService extends AtomService { - private Map workspaceMap = new TreeMap(); - private Map collectionMap = new TreeMap(); - private static Properties cacheProps = new Properties(); - private boolean firstTime = true; - - /** - * Creates a new instance of FileBasedAtomService. - */ - public FileBasedAtomService( - String userName, String baseDir, String contextURI, String contextPath, String servletPath) throws Exception { - String workspaceHandle = userName; - - // One workspace per user - FileBasedWorkspace workspace = new FileBasedWorkspace(workspaceHandle, baseDir); - workspaceMap.put(userName, workspace); - - if (firstTime) { - synchronized(cacheProps) { - InputStream is = getClass().getResourceAsStream("/propono.properties"); - if (is != null) cacheProps.load(is); - firstTime = false; - } - } - // can't find propono.properties, so use system props instead - if (cacheProps == null) cacheProps = System.getProperties(); - - String relativeURIsString = cacheProps.getProperty( - "propono.atomserver.filebased.relativeURIs"); - boolean relativeURIs = "true".equals(relativeURIsString); - - String inlineCategoriesString = cacheProps.getProperty( - "propono.atomserver.filebased.inlineCategories"); - boolean inlineCategories = "true".equals(inlineCategoriesString); - - String colnames = cacheProps.getProperty("propono.atomserver.filebased.collections"); - if (colnames != null) { - - // collections specified in propono.properties, use those - - String[] colarray = Utilities.stringToStringArray(colnames,","); - for (int i=0; i[collection-plural]/[entryid]/media/[entryid]. - * An Atom entry will be created to store metadata for the entry and it will exist - * at the path [collection-plural]/[entryid]/entry.xml. - * The entry will be added to the collection's feed in [collection-plural]/feed.xml. - * @param entry Entry object - * @param slug String to be used in file-name - * @param is Source of media data - * @throws java.lang.Exception On Error - * @return Location URI of entry - */ - public String addMediaEntry(Entry entry, String slug, InputStream is) throws Exception { - synchronized (FileStore.getFileStore()) { - - // Save media file temp file - Content content = (Content)entry.getContents().get(0); - if (entry.getTitle() == null) { - entry.setTitle(slug); - } - String fileName = createFileName((slug != null) ? slug : entry.getTitle(), content.getType()); - File tempFile = File.createTempFile(fileName, "tmp"); - FileOutputStream fos = new FileOutputStream(tempFile); - Utilities.copyInputToOutput(is, fos); - fos.close(); - - // Save media file - FileInputStream fis = new FileInputStream(tempFile); - saveMediaFile(fileName, content.getType(), tempFile.length(), fis); - fis.close(); - File resourceFile = new File(getEntryMediaPath(fileName)); - - // Create media-link entry - updateTimestamps(entry); - - // Save media-link entry - String entryPath = getEntryPath(fileName); - OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); - updateMediaEntryAppLinks(entry, resourceFile.getName(), true); - Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8")); - os.flush(); - os.close(); - - // Update feed with new entry - Feed f = getFeedDocument(); - updateMediaEntryAppLinks(entry, resourceFile.getName(), false); - updateFeedDocumentWithNewEntry(f, entry); - - return getEntryEditURI(fileName, false, true); - } - } - - /** - * Get an entry from the collection. - * @param fsid Internal ID of entry to be returned - * @throws java.lang.Exception On error - * @return Entry specified by fileName/ID - */ - public Entry getEntry(String fsid) throws Exception { - if (fsid.endsWith(".media-link")) { - fsid = fsid.substring(0, fsid.length() - ".media-link".length()); - } - - String entryPath = getEntryPath(fsid); - - checkExistence(entryPath); - InputStream in = FileStore.getFileStore().getFileInputStream(entryPath); - - final Entry entry; - String filePath = getEntryMediaPath(fsid); - File resource = new File(fsid); - if (resource.exists()) { - entry = loadAtomResourceEntry(in, resource); - updateMediaEntryAppLinks(entry, fsid, true); - } else { - entry = loadAtomEntry(in); - updateEntryAppLinks(entry, fsid, true); - } - return entry; - } - - /** - * Get media resource wrapping a file. - */ - public AtomMediaResource getMediaResource(String fileName) throws Exception { - String filePath = getEntryMediaPath(fileName); - File resource = new File(filePath); - return new AtomMediaResource(resource); - } - - /** - * Update an entry in the collection. - * @param entry Updated entry to be stored - * @param fsid Internal ID of entry - * @throws java.lang.Exception On error - */ - public void updateEntry(Entry entry, String fsid) throws Exception { - synchronized (FileStore.getFileStore()) { - - Feed f = getFeedDocument(); - - if (fsid.endsWith(".media-link")) { - fsid = fsid.substring(0, fsid.length() - ".media-link".length()); - } - - updateTimestamps(entry); - - updateEntryAppLinks(entry, fsid, false); - updateFeedDocumentWithExistingEntry(f, entry); - - String entryPath = getEntryPath(fsid); - OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); - updateEntryAppLinks(entry, fsid, true); - Atom10Generator.serializeEntry(entry, new OutputStreamWriter(os, "UTF-8")); - os.flush(); - os.close(); - } - } - - /** - * Update media associated with a media-link entry. - * @param fileName Internal ID of entry being updated - * @param contentType Content type of data - * @param is Source of updated data - * @throws java.lang.Exception On error - * @return Updated Entry as it exists on server - */ - public Entry updateMediaEntry(String fileName, String contentType, InputStream is) throws Exception { - synchronized (FileStore.getFileStore()) { - - File tempFile = File.createTempFile(fileName, "tmp"); - FileOutputStream fos = new FileOutputStream(tempFile); - Utilities.copyInputToOutput(is, fos); - fos.close(); - - // Update media file - FileInputStream fis = new FileInputStream(tempFile); - saveMediaFile(fileName, contentType, tempFile.length(), fis); - fis.close(); - File resourceFile = new File(getEntryMediaPath(fileName)); - - // Load media-link entry to return - String entryPath = getEntryPath(fileName); - InputStream in = FileStore.getFileStore().getFileInputStream(entryPath); - Entry atomEntry = loadAtomResourceEntry(in, resourceFile); - - updateTimestamps(atomEntry); - updateMediaEntryAppLinks(atomEntry, fileName, false); - - // Update feed with new entry - Feed f = getFeedDocument(); - updateFeedDocumentWithExistingEntry(f, atomEntry); - - // Save updated media-link entry - OutputStream os = FileStore.getFileStore().getFileOutputStream(entryPath); - updateMediaEntryAppLinks(atomEntry, fileName, true); - Atom10Generator.serializeEntry(atomEntry, new OutputStreamWriter(os, "UTF-8")); - os.flush(); - os.close(); - - return atomEntry; - } - } - - /** - * Delete an entry and any associated media file. - * @param fsid Internal ID of entry - * @throws java.lang.Exception On error - */ - public void deleteEntry(String fsid) throws Exception { - synchronized (FileStore.getFileStore()) { - - // Remove entry from Feed - Feed feed = getFeedDocument(); - updateFeedDocumentRemovingEntry(feed, fsid); - - String entryFilePath = this.getEntryPath(fsid); - FileStore.getFileStore().deleteFile(entryFilePath); - - String entryMediaPath = this.getEntryMediaPath(fsid); - if (entryMediaPath != null) { - FileStore.getFileStore().deleteFile(entryMediaPath); - } - - String entryDirPath = getEntryDirPath(fsid); - FileStore.getFileStore().deleteDirectory(entryDirPath); - - try {Thread.sleep(500L);}catch(Exception ignored){} - } - } - - private void updateFeedDocumentWithNewEntry(Feed f, Entry e) throws AtomException { - boolean inserted = false; - for (int i=0; iRepresents a blog, which has collections of entries and resources. - * You can access the collections using the getCollections() and - * getCollection(String name) methods, which return Blog.Collection objects, - * which you can use to create, retrieve update or delete entries within - * a collection.

- */ -public interface Blog { - - /** - * Token can be used to fetch this blog again from getBlog() method. - * @return Blog object specified by token. - */ - public String getToken(); - - /** - * Name of this blog. - * @return Display name of this blog. - */ - public String getName(); - - /** - * Get a single BlogEntry (or BlogResource) by token. - * @param token Token from blog entry's getToken() method. - * @throws com.sun.syndication.propono.blogclient.BlogClientException On error fetching the blog entry. - * @return Blog entry specified by token. - */ - public BlogEntry getEntry(String token) throws BlogClientException; - - /** - * Gets listing of entry and resource collections available in the blog, - * including the primary collections. - * @throws BlogClientException On error fetching collections. - * @return List of Blog.Collection objects. - */ - public List getCollections() throws BlogClientException; - - /** - * Get collection by token. - * @param token Token from a collection's getToken() method. - * @throws BlogClientException On error fetching collection. - * @return Blog.Collection object. - */ - public Collection getCollection(String token) throws BlogClientException; - - /** - * Represents an entry or resource collection on a blog server. - */ - public interface Collection { - - /** - * Get blog that contains this collection. - * @return Blog that contains this collection. - */ - public Blog getBlog(); - - /** - * Title of collection. - * @return Title of collecton. - */ - public String getTitle(); - - /** - * Token that can be used to fetch collection. - * @return Token that can be used to fetch collection. - */ - public String getToken(); - - /** - * Content-types accepted by collection. - * @return Comma-separated list of content-types accepted. - */ - public List getAccepts(); - - /** - * Determines if collection will accept a content-type. - * @param contentType Content-type to be considered. - * @return True of content type will be accepted, false otherwise. - */ - public boolean accepts(String contentType); - - /** - * Return categories allowed by colletion. - * @throws BlogClientException On error fetching categories. - * @return List of BlogEntry.Category objects for this collection. - */ - public List getCategories() throws BlogClientException; - - /** - * Create but do not save new entry in collection. - * To save entry, call its save() method. - * @throws BlogClientException On error creating entry. - * @return New BlogEntry object. - */ - public BlogEntry newEntry() throws BlogClientException; - - /** - * Create but do not save new resource in collection. - * To save resource, call its save() method. - * @param name Name of new resource. - * @param contentType MIME content-type of new resource. - * @param bytes Data for new resource. - * @throws BlogClientException On error creating entry. - * @return New BlogResource object, - */ - public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException; - - /** - * Get iterator over entries/resources in this collection. - * @return List of BlogEntry objects, some may be BlogResources. - * @throws BlogClientException On error fetching entries/resources. - */ - public Iterator getEntries() throws BlogClientException; - - /** - * Save or update a BlogEntry in this collection by adding it to this - * collection and then calling it's entry.save() method. - * @param entry BlogEntry to be saved. - * @throws BlogClientException On error saving entry. - * @return URI of entry. - */ - public String saveEntry(BlogEntry entry) throws BlogClientException; - - /** - * Save or update resource in this collection - * @param resource BlogResource to be saved. - * @throws BlogClientException On error saving resource. - * @return URI of resource. - */ - public String saveResource(BlogResource resource) throws BlogClientException; - } - - - // Deprecated primary collection methods, instead use collections directly. - - /** - * Get iterator over entries in primary entries collection (the first - * collection that accepts entries). Note that entries may be partial, - * so don't try to update and save them: to update and entry, first fetch - * it with getEntry(), change fields, then call entry.save(); - * @return To iterate over all entries in collection. - * @throws BlogClientException On failure or if there is no primary entries collection. - * - * @deprecated Instead use collections directly. - */ - public Iterator getEntries() throws BlogClientException; - - /** - * Get entries in primary resources collection (the first - * collection that accepts anything other than entries). - * @throws BlogClientException On failure or if there is no primary resources collection. - * @return To iterate over all resojrces in collection. - * - * @deprecated Instead use collections directly. - */ - public Iterator getResources() throws BlogClientException; - - - /** - * Create but do not save it to server new BlogEntry in primary entries collection - * (the first collection found that accepts entries). To save the entry to the - * server to a collection, use the entry's save() method. - * @throws BlogClientException On error or if there is no primary entries collection. - * @return Unsaved BlogEntry in primary entries collection. - * - * @deprecated Instead use collections directly. - */ - public BlogEntry newEntry() throws BlogClientException; - - /** - * Create but do not save it to server new BlogResource in primary resources collection - * (the first collection found that accepts resources). To save the resource to the - * server to a collection, use the resource's save() method. - * @param name Name of resource to be saved. - * @param type MIME content type of resource data. - * @param bytes Bytes of resource data. - * @throws BlogClientException On error or if there is no primary respurces collection. - * @return Unsaved BlogEntry in primary resources collection. - * - * @deprecated Instead use collections directly. - */ - public BlogResource newResource(String name, String type, byte[] bytes) - throws BlogClientException; - - /** - * Returns list of available BlogEntry.Category in primary entries collection. - * @throws BlogClientException On error or if there is no primary entries collection. - * @return List of BlogEntry.Category objects. - * - * @deprecated Instead use collections directly. - */ - public List getCategories() throws BlogClientException; -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/BlogClientException.java b/src/main/java/com/sun/syndication/propono/blogclient/BlogClientException.java deleted file mode 100644 index b982a5a..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/BlogClientException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient; - -/** - * Represents a Blog Client exception, the library throws these instead of - * implementation specific exceptions. - */ -public class BlogClientException extends Exception { - - /** - * Construct a new exception - * @param msg Text message that explains exception - */ - public BlogClientException(String msg) { - super(msg); - } - - /** - * Construct a new exception which wraps a throwable. - * @param msg Text message that explains exception - * @param t Throwable to be wrapped by exception - */ - public BlogClientException(String msg, Throwable t) { - super(msg, t); - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/BlogConnection.java b/src/main/java/com/sun/syndication/propono/blogclient/BlogConnection.java deleted file mode 100644 index e889f9b..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/BlogConnection.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient; - -import java.util.List; - -/** - * A BlogConnection is a single-user connection to a blog server where the user - * has access to multiple blogs, which are each represented by a Blog interface. - */ -public interface BlogConnection { - - /** Returns collection of blogs available from this connection */ - public abstract List getBlogs(); - - /** Get blog by token */ - public abstract Blog getBlog(String token); - - /** Set appkey (optional, needed by some blog servers) */ - public void setAppkey(String appkey); -} \ No newline at end of file diff --git a/src/main/java/com/sun/syndication/propono/blogclient/BlogConnectionFactory.java b/src/main/java/com/sun/syndication/propono/blogclient/BlogConnectionFactory.java deleted file mode 100644 index 0f9945f..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/BlogConnectionFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient; - -import java.lang.reflect.Constructor; - -/** - * Entry point to the Blogapps blog client library. - */ -public class BlogConnectionFactory { - - // BlogConnection implementations must: - // 1) implement BlogConnection - // 2) privide contructor that accepts three strings args: url, username and password. - - // TODO: make implementations configurable - private static String ATOMPROTOCOL_IMPL_CLASS = - "com.sun.syndication.propono.blogclient.atomprotocol.AtomConnection"; - - private static String METAWEBLOG_IMPL_CLASS = - "com.sun.syndication.propono.blogclient.metaweblog.MetaWeblogConnection"; - - /** - * Create a connection to a blog server. - * @param type Connection type, must be "atom" or "metaweblog" - * @param url End-point URL to connect to - * @param username Username for login to blog server - * @param password Password for login to blog server - */ - public static BlogConnection getBlogConnection( - String type, String url, String username, String password) - throws BlogClientException { - BlogConnection blogConnection = null; - if (type == null || type.equals("metaweblog")) { - blogConnection = createBlogConnection( - METAWEBLOG_IMPL_CLASS, url, username, password); - } else if (type.equals("atom")) { - blogConnection = createBlogConnection( - ATOMPROTOCOL_IMPL_CLASS, url, username, password); - } else { - throw new BlogClientException("Type must be 'atom' or 'metaweblog'"); - } - return blogConnection; - } - - private static BlogConnection createBlogConnection( - String className, String url, String username, String password) - throws BlogClientException { - Class conClass; - try { - conClass = Class.forName(className); - } catch (ClassNotFoundException ex) { - throw new BlogClientException( - "BlogConnection impl. class not found: "+className, ex); - } - Class[] args = new Class[] {String.class, String.class, String.class}; - Constructor ctor; - try { - ctor = conClass.getConstructor(args); - return (BlogConnection) - ctor.newInstance(new Object[] {url, username, password}); - } catch (Throwable t) { - throw new BlogClientException( - "ERROR instantiating BlogConnection impl.", t); - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/BlogEntry.java b/src/main/java/com/sun/syndication/propono/blogclient/BlogEntry.java deleted file mode 100644 index be79697..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/BlogEntry.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient; - -import java.util.Date; -import java.util.List; -import java.io.InputStream; - -/** - * Represents a single blog entry. - */ -public interface BlogEntry { - - /** Get token, which can be used to fetch the blog entry */ - public String getToken(); - - /** - * Save this entry to it's collection. If this is a new entry and does not - * have a collection yet, then save() will save it to the primary collection. - */ - public void save() throws BlogClientException; - - /** Delete this entry from blog server */ - public void delete() throws BlogClientException; - - /** Permanent link to this entry (assigned by server) */ - public String getPermalink(); - - /** Blog is associated with a blog */ - public Blog getBlog(); - - /** Get categories, a list of BlogEntry.Category objects */ - public List getCategories(); - - /** Set categories, a list of BlogEntry.Category objects */ - public void setCategories(List categories); - - /** Get globally unique ID of this blog entry */ - public String getId(); - - /** Get title of this blog entry */ - public String getTitle(); - - /** Set title of this blog entry */ - public void setTitle(String title); - - /** Get summary of this blog entry */ - public String getSummary(); - - /** Set summary of this blog entry */ - public void setSummary(String summary); - - /** Get content of this blog entry */ - public Content getContent(); - - /** Set content of this blog entry */ - public void setContent(Content content); - - /** Get draft status of this entry */ - public boolean getDraft(); - - /** Set draft status of this entry */ - public void setDraft(boolean draft); - - /** Get author of this entry */ - public Person getAuthor(); - - /** Set author of this entry */ - public void setAuthor(Person author); - - /** Set publish date of this entry */ - public Date getPublicationDate(); - - /** Get publish date of this entry */ - public void setPublicationDate(Date date); - - /** Get update date of this entry */ - public Date getModificationDate(); - - /** Set update date of this entry */ - public void setModificationDate(Date date); - - /** Represents blog entry content */ - public class Content { - String type = "html"; - String value = null; - String src = null; - - /** Construct content */ - public Content() {} - - /** Construct content with value (and type="html") */ - public Content(String value) { - this.value = value; - } - /** Get value of content if in-line */ - public String getValue() { - return value; - } - /** Set value of content if in-line */ - public void setValue(String value) { - this.value = value; - } - /** - * Get type of content, either "text", "html", "xhtml" or a MIME content-type. - * Defaults to HTML. - */ - public String getType() { - return type; - } - /** - * Set type of content, either "text", "html", "xhtml" or a MIME content-type. - * Defaults to HTML. - */ - public void setType(String type) { - this.type = type; - } - /** Get URI of content if out-of-line */ - public String getSrc() { - return src; - } - /** Set URI of content if out-of-line */ - public void setSrc(String src) { - this.src = src; - } - } - - /** Represents a blog author or contributor */ - public class Person { - String name; - String email; - String url; - /** Get person's email */ - public String getEmail() { - return email; - } - /** Set person's email */ - public void setEmail(String email) { - this.email = email; - } - /** Get person's name */ - public String getName() { - return name; - } - /** Set person's name */ - public void setName(String name) { - this.name = name; - } - /** Get person's URL */ - public String getUrl() { - return url; - } - /** Set person's URL */ - public void setUrl(String url) { - this.url = url; - } - /** Returns person's name */ - public String toString() { - return name; - } - } - - /** Represents a weblog category */ - public class Category { - String id; - String name; - String url; - /** - * Create new Catetory - */ - public Category() {} - /** - * Create new category with name. - */ - public Category(String id) { - this.id = id; - this.name = id; - } - /** - * Determines if categories are equal based on id. - */ - public boolean equals(Object obj) { - Category other = (Category)obj; - if (obj == null) return false; - if (getId() != null && other.getId() != null - && getId().equals(other.getId())) return true; - return false; - } - /** Get category id */ - public String getId() { - return id; - } - /** Set category id */ - public void setId(String id) { - this.id = id; - } - /** Get category display name */ - public String getName() { - return name; - } - /** Set category display name */ - public void setName(String name) { - this.name = name; - } - /** Get URL of category domain */ - public String getUrl() { - return url; - } - /** Set URL of category domain */ - public void setUrl(String url) { - this.url = url; - } - /** Return category's name or id for display */ - public String toString() { - return name!=null ? name : id; - } - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/BlogResource.java b/src/main/java/com/sun/syndication/propono/blogclient/BlogResource.java deleted file mode 100644 index 5e7043e..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/BlogResource.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient; - -import java.io.InputStream; - -/** - * Represents a file that has been uploaded to a blog. - *

- * Resources are modeled as a type of BlogEntry, but be aware: not all servers - * can save resource metadata (i.e. title, category, author, etc.). MetaWeblog - * based servers can't save metadata at all and Atom protocol servers are not - * required to preserve uploaded file metadata. - */ -public interface BlogResource extends BlogEntry { - - /** Get resource name (name is required) */ - public String getName(); - - /** Get resource as stream, using content.src as URL */ - public InputStream getAsStream() throws BlogClientException; - - /** Update resource by immediately uploading new bytes to server */ - public void update(byte[] newBytes) throws BlogClientException; -} - diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomBlog.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomBlog.java deleted file mode 100644 index 9da2b20..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomBlog.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import com.sun.syndication.propono.utils.ProponoException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import com.sun.syndication.propono.blogclient.Blog; -import com.sun.syndication.propono.blogclient.BlogClientException; -import com.sun.syndication.propono.blogclient.BlogEntry; -import com.sun.syndication.propono.blogclient.BlogResource; -import com.sun.syndication.propono.atom.client.ClientAtomService; -import com.sun.syndication.propono.atom.client.ClientCollection; -import com.sun.syndication.propono.atom.client.ClientEntry; -import com.sun.syndication.propono.atom.client.ClientMediaEntry; -import com.sun.syndication.propono.atom.client.ClientWorkspace; -import java.util.Map; -import java.util.TreeMap; - -/** - * Atom protocol implementation of the BlogClient Blog interface. - */ -public class AtomBlog implements Blog { - static final Log logger = LogFactory.getLog(AtomBlog.class); - private HttpClient httpClient = null; - private String name = null; - private ClientAtomService service; - private ClientWorkspace workspace = null; - private AtomCollection entriesCollection = null; - private AtomCollection resourcesCollection = null; - private Map collections = new TreeMap(); - - /** - * Create AtomBlog using specified HTTPClient, user account and workspace, - * called by AtomConnection. Fetches Atom Service document and creates - * an AtomCollection object for each collection found. The first entry - * collection is considered the primary entry collection. And the first - * resource collection is considered the primary resource collection. - */ - AtomBlog(ClientAtomService service, ClientWorkspace workspace) { - this.setService(service); - this.setWorkspace(workspace); - this.name = workspace.getTitle(); - Iterator members = workspace.getCollections().iterator(); - - while (members.hasNext()) { - ClientCollection col = (ClientCollection) members.next(); - if (col.accepts("entry") && entriesCollection == null) { - // first entry collection is primary entry collection - entriesCollection = new AtomCollection(this, col); - } - else if (!col.accepts("entry") && resourcesCollection == null) { - // first non-entry collection is primary resource collection - resourcesCollection = new AtomCollection(this, col); - } - collections.put(col.getHrefResolved(), new AtomCollection(this, col)); - } - } - - /** - * {@inheritDoc} - */ - public String getName() { return name; } - - /** - * String display of blog, returns name. - */ - public String toString() { return getName(); } - - /** - * {@inheritDoc} - */ - public String getToken() { return entriesCollection.getToken(); } - - /** - * {@inheritDoc} - */ - public BlogEntry newEntry() throws BlogClientException { - if (entriesCollection == null) throw new BlogClientException("No entry collection"); - return entriesCollection.newEntry(); - } - - /** - * {@inheritDoc} - */ - public BlogEntry getEntry(String token) throws BlogClientException { - ClientEntry clientEntry = null; - AtomEntry atomEntry = null; - try { - clientEntry = getService().getEntry(token); - } catch (ProponoException ex) { - throw new BlogClientException("ERROR: fetching entry", ex); - } - if (clientEntry != null && clientEntry instanceof ClientMediaEntry) { - return new AtomResource(this, (ClientMediaEntry)clientEntry); - } else if (clientEntry != null && clientEntry instanceof ClientEntry) { - return new AtomEntry(this, clientEntry); - } else { - throw new BlogClientException("ERROR: unknown object type returned"); - } - } - - /** - * {@inheritDoc} - */ - public Iterator getEntries() throws BlogClientException { - if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); - return new AtomEntryIterator(entriesCollection); - } - - /** - * {@inheritDoc} - */ - public Iterator getResources() throws BlogClientException { - if (resourcesCollection == null) throw new BlogClientException("No primary entry collection"); - return new AtomEntryIterator(resourcesCollection); - } - - String saveEntry(BlogEntry entry) throws BlogClientException { - if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); - return entriesCollection.saveEntry(entry); - } - - void deleteEntry(BlogEntry entry) throws BlogClientException { - if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); - entriesCollection.deleteEntry(entry); - } - - /** - * {@inheritDoc} - */ - public List getCategories() throws BlogClientException { - if (entriesCollection == null) throw new BlogClientException("No primary entry collection"); - return entriesCollection.getCategories(); - } - - /** - * {@inheritDoc} - */ - public BlogResource newResource( - String name, String contentType, byte[] bytes) throws BlogClientException { - if (resourcesCollection == null) { - throw new BlogClientException("No resource collection"); - } - return resourcesCollection.newResource(name, contentType, bytes); - } - - - String saveResource(BlogResource res) throws BlogClientException { - if (resourcesCollection == null) throw new BlogClientException("No primary resource collection"); - return resourcesCollection.saveResource(res); - } - - void deleteResource(BlogResource resource) throws BlogClientException { - deleteEntry((BlogEntry)resource); - } - - /** - * {@inheritDoc} - */ - public List getCollections() throws BlogClientException { - return new ArrayList(collections.values()); - } - - /** - * {@inheritDoc} - */ - public Blog.Collection getCollection(String token) throws BlogClientException { - return (Blog.Collection)collections.get(token); - } - - ClientAtomService getService() { - return service; - } - - void setService(ClientAtomService service) { - this.service = service; - } - - ClientWorkspace getWorkspace() { - return workspace; - } - - void setWorkspace(ClientWorkspace workspace) { - this.workspace = workspace; - } - -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomCollection.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomCollection.java deleted file mode 100644 index 1216317..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomCollection.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import com.sun.syndication.feed.atom.Category; -import com.sun.syndication.propono.atom.client.ClientAtomService; -import com.sun.syndication.propono.atom.common.Categories; -import com.sun.syndication.propono.atom.client.ClientCollection; -import com.sun.syndication.propono.atom.client.ClientEntry; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.sun.syndication.propono.blogclient.Blog; -import com.sun.syndication.propono.blogclient.BlogClientException; -import com.sun.syndication.propono.blogclient.BlogEntry; -import com.sun.syndication.propono.blogclient.BlogResource; - -/** - * Atom protocol implementation of BlogClient Blog.Collection. - */ -public class AtomCollection implements Blog.Collection { - static final Log logger = LogFactory.getLog(AtomCollection.class); - - private Blog blog = null; - private List categories = new ArrayList(); - - private ClientCollection clientCollection = null; - - - AtomCollection(AtomBlog blog, ClientCollection col) { - this.blog = blog; - this.clientCollection = col; - for (Iterator catsIter = col.getCategories().iterator(); catsIter.hasNext();) { - Categories cats = (Categories)catsIter.next(); - for (Iterator catIter = cats.getCategories().iterator(); catIter.hasNext();) { - Category cat = (Category)catIter.next(); - BlogEntry.Category blogCat = new BlogEntry.Category(cat.getTerm()); - blogCat.setName(cat.getLabel()); - blogCat.setUrl(cat.getScheme()); - getCategories().add(blogCat); - } - } - } - - /** - * {@inheritDoc} - */ - public String getTitle() { - return getClientCollection().getTitle(); - } - - /** - * {@inheritDoc} - */ - public String getToken() { - return getClientCollection().getHrefResolved(); - } - - /** - * {@inheritDoc} - */ - public List getAccepts() { - return getClientCollection().getAccepts(); - } - - /** - * {@inheritDoc} - */ - public boolean accepts(String ct) { - return getClientCollection().accepts(ct); - } - - /** - * {@inheritDoc} - */ - public Iterator getEntries() throws BlogClientException { - return new AtomEntryIterator(this); - } - - /** - * {@inheritDoc} - */ - public BlogEntry newEntry() throws BlogClientException { - AtomBlog atomBlog = (AtomBlog)getBlog(); - BlogEntry entry = new AtomEntry(atomBlog, this); - return entry; - } - - /** - * {@inheritDoc} - */ - public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException { - return new AtomResource(this, name, contentType, bytes); - } - - /** - * {@inheritDoc} - */ - public String saveResource(BlogResource res) throws BlogClientException { - ((AtomResource)res).setCollection(this); - res.save(); - return res.getContent().getSrc(); - } - - /** - * {@inheritDoc} - */ - public String saveEntry(BlogEntry entry) throws BlogClientException { - ((AtomEntry)entry).setCollection(this); - entry.save(); - return entry.getPermalink(); - } - - void deleteEntry(BlogEntry entry) throws BlogClientException { - try { - ClientAtomService service = ((AtomBlog)getBlog()).getService(); - ClientEntry clientEntry = service.getEntry(entry.getToken()); - clientEntry.remove(); - - } catch (Exception e) { - throw new BlogClientException("ERROR deleting entry", e); - } - } - - /** - * {@inheritDoc} - */ - public Blog getBlog() { - return blog; - } - - void setBlog(AtomBlog blog) { - this.blog = blog; - } - - /** - * {@inheritDoc} - */ - public List getCategories() { - return categories; - } - - void setCategories(List categories) { - this.categories = categories; - } - - ClientCollection getClientCollection() { - return clientCollection; - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomConnection.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomConnection.java deleted file mode 100644 index dc483a4..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomConnection.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import com.sun.syndication.propono.atom.client.AtomClientFactory; -import com.sun.syndication.propono.atom.client.BasicAuthStrategy; -import com.sun.syndication.propono.atom.client.ClientAtomService; -import com.sun.syndication.propono.atom.client.ClientWorkspace; -import java.util.List; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.jdom.Document; - -import com.sun.syndication.propono.blogclient.BlogConnection; -import com.sun.syndication.propono.blogclient.Blog; -import com.sun.syndication.propono.blogclient.BlogClientException; - - -/** - * Atom protocol of BlogConnection. Connects to Atom server, creates AtomBlog - * object for each Atom workspace found and within each blog a collection for each - * Atom collection found. - */ -public class AtomConnection implements BlogConnection { - private static Log logger = LogFactory.getLog(AtomConnection.class); - private HttpClient httpClient = null; - private Map blogs = new HashMap(); - - /** - * Create Atom blog client instance for specified URL and user account. - * @param uri End-point URL of Atom service - * @param username Username of account - * @param password Password of account - */ - public AtomConnection(String uri, String username, String password) - throws BlogClientException { - - Document doc = null; - try { - ClientAtomService service = (ClientAtomService) - AtomClientFactory.getAtomService(uri, new BasicAuthStrategy(username, password)); - Iterator iter = service.getWorkspaces().iterator(); - int count = 0; - while (iter.hasNext()) { - ClientWorkspace workspace = (ClientWorkspace)iter.next(); - Blog blog = new AtomBlog(service, workspace); - blogs.put(blog.getToken(), blog); - } - } catch (Throwable t) { - throw new BlogClientException("Error connecting to blog server", t); - } - } - - /** - * {@inheritDoc} - */ - public List getBlogs() { - return new ArrayList(blogs.values()); - } - - /** - * {@inheritDoc} - */ - public Blog getBlog(String token) { - return (AtomBlog)blogs.get(token); - } - - /** - * {@inheritDoc} - */ - public void setAppkey(String appkey) { - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntry.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntry.java deleted file mode 100644 index 59deaef..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntry.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import com.sun.syndication.propono.utils.ProponoException; -import com.sun.syndication.propono.atom.common.rome.AppModule; -import com.sun.syndication.propono.atom.common.rome.AppModuleImpl; -import com.sun.syndication.propono.blogclient.BlogClientException; -import com.sun.syndication.propono.blogclient.BlogEntry; -import com.sun.syndication.propono.blogclient.BaseBlogEntry; -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import com.sun.syndication.feed.atom.Entry; -import com.sun.syndication.feed.atom.Link; -import com.sun.syndication.propono.atom.client.ClientEntry; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.sun.syndication.propono.blogclient.BlogEntry.Person; - -/** - * Atom protocol implementation of BlogEntry. - */ -public class AtomEntry extends BaseBlogEntry implements BlogEntry { - static final Log logger = LogFactory.getLog(AtomCollection.class); - - String editURI = null; - AtomCollection collection = null; - - AtomEntry(AtomBlog blog, AtomCollection collection) throws BlogClientException { - super(blog); - this.collection = collection; - } - - AtomEntry(AtomCollection collection, ClientEntry entry) throws BlogClientException { - this((AtomBlog)collection.getBlog(), collection); - //clientEntry = entry; - copyFromRomeEntry(entry); - } - - AtomEntry(AtomBlog blog, ClientEntry entry) throws BlogClientException { - super(blog); - //clientEntry = entry; - copyFromRomeEntry(entry); - } - - /** - * {@inheritDoc} - */ - public String getToken() { - return editURI; - } - - AtomCollection getCollection() { - return collection; - } - - void setCollection(AtomCollection collection) { - this.collection = collection; - } - - /** - * True if entry's token's are equal. - */ - public boolean equals(Object o) { - if (o instanceof AtomEntry) { - AtomEntry other = (AtomEntry)o; - if (other.getToken() != null && getToken() != null) { - return other.getToken().equals(getToken()); - } - } - return false; - } - - /** - * {@inheritDoc} - */ - public void save() throws BlogClientException { - boolean create = (getToken() == null); - if (create && getCollection() == null) { - throw new BlogClientException("Cannot save entry, no collection"); - } else if (create) { - try { - ClientEntry clientEntry = collection.getClientCollection().createEntry(); - copyToRomeEntry(clientEntry); - collection.getClientCollection().addEntry(clientEntry); - copyFromRomeEntry(clientEntry); - } catch (ProponoException ex) { - throw new BlogClientException("Error saving entry", ex); - } - } else { - try { - ClientEntry clientEntry = ((AtomBlog)getBlog()).getService().getEntry(getToken()); - copyToRomeEntry(clientEntry); - clientEntry.update(); - copyFromRomeEntry(clientEntry); - } catch (ProponoException ex) { - throw new BlogClientException("Error updating entry", ex); - } - } - } - - /** - * {@inheritDoc} - */ - public void delete() throws BlogClientException { - if (getToken() == null) { - throw new BlogClientException("Cannot delete unsaved entry"); - } - try { - ClientEntry clientEntry = ((AtomBlog)getBlog()).getService().getEntry(editURI); - clientEntry.remove(); - } catch (ProponoException ex) { - throw new BlogClientException("Error removing entry", ex); - } - } - - void copyFromRomeEntry(ClientEntry entry) { - id = entry.getId(); - title = entry.getTitle(); - editURI = entry.getEditURI(); - List altlinks = entry.getAlternateLinks(); - if (altlinks != null) { - for (Iterator iter = altlinks.iterator(); iter.hasNext();) { - Link link = (Link)iter.next(); - if ("alternate".equals(link.getRel()) || link.getRel()==null) { - permalink = link.getHrefResolved(); - break; - } - } - } - List contents = entry.getContents(); - com.sun.syndication.feed.atom.Content romeContent = null; - if (contents != null && contents.size() > 0) { - romeContent = (com.sun.syndication.feed.atom.Content)contents.get(0); - } - if (romeContent != null) { - content = new BlogEntry.Content(romeContent.getValue()); - content.setType(romeContent.getType()); - content.setSrc(romeContent.getSrc()); - } - if (entry.getCategories() != null) { - List cats = new ArrayList(); - List romeCats = entry.getCategories(); - for (Iterator iter=romeCats.iterator(); iter.hasNext();) { - com.sun.syndication.feed.atom.Category romeCat = - (com.sun.syndication.feed.atom.Category)iter.next(); - BlogEntry.Category cat = new BlogEntry.Category(); - cat.setId(romeCat.getTerm()); - cat.setUrl(romeCat.getScheme()); - cat.setName(romeCat.getLabel()); - cats.add(cat); - } - categories = cats; - } - List authors = entry.getAuthors(); - if (authors!=null && authors.size() > 0) { - com.sun.syndication.feed.atom.Person romeAuthor = - (com.sun.syndication.feed.atom.Person)authors.get(0); - if (romeAuthor != null) { - author = new Person(); - author.setName(romeAuthor.getName()); - author.setEmail(romeAuthor.getEmail()); - author.setUrl(romeAuthor.getUrl()); - } - } - publicationDate = entry.getPublished(); - modificationDate = entry.getModified(); - - AppModule control = (AppModule)entry.getModule(AppModule.URI); - if (control != null && control.getDraft() != null) { - draft = control.getDraft().booleanValue(); - } else { - draft = false; - } - } - Entry copyToRomeEntry(ClientEntry entry) { - if (id != null) { - entry.setId(id); - } - entry.setTitle(title); - if (author != null) { - com.sun.syndication.feed.atom.Person person = - new com.sun.syndication.feed.atom.Person(); - person.setName(author.getName()); - person.setEmail(author.getEmail()); - person.setUrl(author.getUrl()); - List authors = new ArrayList(); - authors.add(person); - entry.setAuthors(authors); - } - if (content != null) { - com.sun.syndication.feed.atom.Content romeContent = - new com.sun.syndication.feed.atom.Content(); - romeContent.setValue(content.getValue()); - romeContent.setType(content.getType()); - List contents = new ArrayList(); - contents.add(romeContent); - entry.setContents(contents); - } - if (categories != null) { - List romeCats = new ArrayList(); - for (Iterator iter=categories.iterator(); iter.hasNext();) { - BlogEntry.Category cat = (BlogEntry.Category)iter.next(); - com.sun.syndication.feed.atom.Category romeCategory = - new com.sun.syndication.feed.atom.Category(); - romeCategory.setTerm(cat.getId()); - romeCategory.setScheme(cat.getUrl()); - romeCategory.setLabel(cat.getName()); - romeCats.add(romeCategory); - } - entry.setCategories(romeCats); - } - entry.setPublished((publicationDate == null) ? new Date() : publicationDate); - entry.setModified((modificationDate == null) ? new Date() : modificationDate); - - List modules = new ArrayList(); - AppModule control = new AppModuleImpl(); - control.setDraft(new Boolean(draft)); - modules.add(control); - entry.setModules(modules); - - return entry; - } - -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntryIterator.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntryIterator.java deleted file mode 100644 index 9191c15..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomEntryIterator.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import com.sun.syndication.propono.atom.client.ClientEntry; -import com.sun.syndication.propono.atom.client.ClientMediaEntry; -import java.util.Iterator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import com.sun.syndication.propono.blogclient.BlogClientException; - -/** - * Atom protocol implementation of BlogClient entry iterator. - */ -public class AtomEntryIterator implements Iterator { - static final Log logger = LogFactory.getLog(AtomEntryIterator.class); - private Iterator iterator = null; - private AtomCollection collection = null; - - AtomEntryIterator(AtomCollection collection) throws BlogClientException { - try { - this.collection = collection; - iterator = collection.getClientCollection().getEntries(); - } catch (Exception e) { - throw new BlogClientException("ERROR fetching collection", e); - } - } - - /** - * True if more entries are available. - */ - public boolean hasNext() { - return iterator.hasNext(); - } - - /** - * Get next entry. - */ - public Object next() { - try { - ClientEntry entry = (ClientEntry)iterator.next(); - if (entry instanceof ClientMediaEntry) { - return new AtomResource(collection, (ClientMediaEntry)entry); - } else { - return new AtomEntry(collection, entry); - } - } catch (Exception e) { - logger.error("ERROR fetching entry", e); - } - return null; - } - - /** - * Remove is not supported. - */ - public void remove() { - // optional method, not implemented - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomResource.java b/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomResource.java deleted file mode 100644 index 455cb9e..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/atomprotocol/AtomResource.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.atomprotocol; - -import java.io.InputStream; - -import com.sun.syndication.propono.blogclient.BlogClientException; -import com.sun.syndication.propono.blogclient.BlogEntry; -import com.sun.syndication.propono.blogclient.BlogResource; -import com.sun.syndication.feed.atom.Link; -import com.sun.syndication.propono.atom.client.ClientAtomService; -import com.sun.syndication.propono.atom.client.ClientCollection; -import com.sun.syndication.propono.atom.client.ClientEntry; -import com.sun.syndication.propono.atom.client.ClientMediaEntry; -import java.util.Iterator; -import java.util.List; - -/** - * Atom protocol implementation of BlogResource. - */ -public class AtomResource extends AtomEntry implements BlogResource { - private AtomCollection collection; - private byte[] bytes; - - AtomResource(AtomCollection collection, String name, String contentType, byte[] bytes) - throws BlogClientException { - super((AtomBlog)collection.getBlog(), collection); - this.collection = collection; - this.bytes = bytes; - BlogEntry.Content rcontent = new BlogEntry.Content(); - rcontent.setType(contentType); - setContent(rcontent); - } - - AtomResource(AtomCollection collection, ClientMediaEntry entry) - throws BlogClientException { - super(collection, entry); - } - - AtomResource(AtomBlog blog, ClientMediaEntry entry) throws BlogClientException { - super(blog, entry); - } - - /** - * {@inheritDoc} - */ - public String getName() { - return getTitle(); - } - - byte[] getBytes() { - return bytes; - } - - /** - * {@inheritDoc} - */ - public InputStream getAsStream() throws BlogClientException { - try { - return null; //((ClientMediaEntry)clientEntry).getAsStream(); - } catch (Exception e) { - throw new BlogClientException("Error creating entry", e); - } - } - - /** - * {@inheritDoc} - */ - public void save() throws BlogClientException { - try { - if (getToken() == null) { - ClientAtomService clientService = ((AtomBlog)getBlog()).getService(); - ClientCollection clientCollection = collection.getClientCollection(); - - ClientMediaEntry clientEntry = - new ClientMediaEntry(clientService, clientCollection, getTitle(), - "", getContent().getType(), getBytes()); - - copyToRomeEntry(clientEntry); - collection.getClientCollection().addEntry(clientEntry); - this.editURI = clientEntry.getEditURI(); - - } else { - ClientAtomService clientService = ((AtomBlog)getBlog()).getService(); - ClientMediaEntry clientEntry = (ClientMediaEntry)clientService.getEntry(editURI); - clientEntry.update(); - } - } catch (Exception e) { - throw new BlogClientException("Error creating entry", e); - } - } - - /** - * {@inheritDoc} - */ - public void update(byte[] newBytes) throws BlogClientException { - try { - //((ClientMediaEntry)clientEntry).setBytes(newBytes); - //clientEntry.update(); - } catch (Exception e) { - throw new BlogClientException("Error creating entry", e); - } - } - - void copyFromRomeEntry(ClientEntry entry) { - super.copyFromRomeEntry(entry); - - List links = entry.getOtherLinks(); - if (links != null) { - for (Iterator iter = links.iterator(); iter.hasNext();) { - Link link = (Link)iter.next(); - if ("edit-media".equals(link.getRel())) { - id = link.getHrefResolved(); - break; - } - } - } - - - } -} diff --git a/src/main/java/com/sun/syndication/propono/blogclient/blogclient-diagram.gif b/src/main/java/com/sun/syndication/propono/blogclient/blogclient-diagram.gif deleted file mode 100644 index 35dac526bed67592e2a4feec37d8976085639158..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18568 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%0D!jTfva(!C|1XZW%AL+Rc88JL0Y&Xby6>Ur|zR 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 XQbb8sAT=&92?75s006xx0000xKC_ZD diff --git a/src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogBlog.java b/src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogBlog.java deleted file mode 100644 index 5c531b3..0000000 --- a/src/main/java/com/sun/syndication/propono/blogclient/metaweblog/MetaWeblogBlog.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright 2007 Dave Johnson (Blogapps project) - * - * 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 com.sun.syndication.propono.blogclient.metaweblog; - -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; -import com.sun.syndication.propono.blogclient.BlogEntry; -import com.sun.syndication.propono.blogclient.Blog; -import com.sun.syndication.propono.blogclient.BlogClientException; -import com.sun.syndication.propono.blogclient.BlogResource; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.TreeMap; -import org.apache.xmlrpc.client.XmlRpcClient; -import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; - -/** - * Blog implementation that uses a mix of Blogger and MetaWeblog API methods. - */ -public class MetaWeblogBlog implements Blog { - private String blogid; - private String name; - private URL url; - private String userName; - private String password; - private String appkey = "dummy"; - private Map collections; - - private XmlRpcClient xmlRpcClient = null; - - /** - * {@inheritDoc} - */ - public String getName() { return name; } - - /** - * {@inheritDoc} - */ - public String getToken() { return blogid; } - - /** - * String representation of blog, returns the name. - */ - public String toString() { return getName(); } - - private XmlRpcClient getXmlRpcClient() { - - if (xmlRpcClient == null) { - XmlRpcClientConfigImpl xmlrpcConfig = new XmlRpcClientConfigImpl(); - xmlrpcConfig.setServerURL(url); - xmlRpcClient = new XmlRpcClient(); - xmlRpcClient.setConfig(xmlrpcConfig); - } - return xmlRpcClient; - } - - MetaWeblogBlog(String blogid, String name, - URL url, String userName, String password) { - this.blogid = blogid; - this.name = name; - this.url = url; - this.userName = userName; - this.password = password; - this.collections = new TreeMap(); - collections.put("entries", - new MetaWeblogBlogCollection(this, "entries", "Entries", "entry")); - collections.put("resources", - new MetaWeblogBlogCollection(this, "resources", "Resources", "*")); - } - - MetaWeblogBlog(String blogId, String name, - URL url, String userName, String password, String appkey) { - this(blogId, name, url, userName, password); - this.appkey = appkey; - } - - /** - * {@inheritDoc} - */ - public BlogEntry newEntry() { - return new MetaWeblogEntry(this, new HashMap()); - } - - String saveEntry(BlogEntry entry) throws BlogClientException { - Blog.Collection col = (Blog.Collection)collections.get("entries"); - return col.saveEntry(entry); - } - - /** - * {@inheritDoc} - */ - public BlogEntry getEntry(String id) throws BlogClientException { - try { - Map result = (Map) - getXmlRpcClient().execute("metaWeblog.getPost", new Object[] {id, userName, password}); - return new MetaWeblogEntry(this, result); - } catch (Exception e) { - throw new BlogClientException("ERROR: XML-RPC error getting entry", e); - } - } - - void deleteEntry(String id) throws BlogClientException { - try { - getXmlRpcClient().execute("blogger.deletePost", - new Object[] {appkey, id, userName, password, Boolean.FALSE}); - } catch (Exception e) { - throw new BlogClientException("ERROR: XML-RPC error getting entry", e); - } - } - - /** - * {@inheritDoc} - */ - public Iterator getEntries() throws BlogClientException { - return new EntryIterator(); - } - - /** - * {@inheritDoc} - */ - public BlogResource newResource(String name, String contentType, byte[] bytes) throws BlogClientException { - return new MetaWeblogResource(this, name, contentType, bytes); - } - - String saveResource(MetaWeblogResource resource) throws BlogClientException { - Blog.Collection col = (Blog.Collection)collections.get("resources"); - return col.saveResource(resource); - } - - BlogResource getResource(String token) throws BlogClientException { - return null; - } - - /** - * {@inheritDoc} - */ - public Iterator getResources() throws BlogClientException { - return new NoOpIterator(); - } - - void deleteResource(BlogResource resource) throws BlogClientException { - // no-op - } - - /** - * {@inheritDoc} - */ - public List getCategories() throws BlogClientException { - - ArrayList ret = new ArrayList(); - try { - Object result = - getXmlRpcClient().execute ("metaWeblog.getCategories", - new Object[] {blogid, userName, password}); - if (result != null && result instanceof HashMap) { - // Standard MetaWeblog API style: struct of struts - Map catsmap = (Map)result; - Iterator keys = catsmap.keySet().iterator(); - while (keys.hasNext()) { - String key = (String)keys.next(); - Map catmap = (Map)catsmap.get(key); - BlogEntry.Category category = new BlogEntry.Category(key); - category.setName((String)catmap.get("description")); - // catmap.get("htmlUrl"); - // catmap.get("rssUrl"); - ret.add(category); - } - } else if (result != null && result instanceof Object[]) { - // Wordpress style: array of structs - Object[] resultArray = (Object[])result; - for (int i=0; i 0) { - List catArray = new ArrayList(); - List cats = getCategories(); - for (int i=0; i Integer.MAX_VALUE) { - // File is too large - } - - // Create the byte array to hold the data - byte[] bytes = new byte[(int)length]; - - // Read in the bytes - int offset = 0; - int numRead = 0; - while (offset < bytes.length - && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { - offset += numRead; - } - - // Ensure all the bytes have been read in - if (offset < bytes.length) { - throw new IOException("Could not completely read file "+file.getName()); - } - - // Close the input stream and return bytes - is.close(); - return bytes; - } - - /** - * Read input from stream and into string. - */ - public static String streamToString(InputStream is) throws IOException { - StringBuffer sb = new StringBuffer(); - BufferedReader in = new BufferedReader(new InputStreamReader(is)); - String line; - while ((line = in.readLine()) != null) { - sb.append(line); - sb.append(LS); - } - return sb.toString(); - } - - /** - * Copy input stream to output stream using 8K buffer. - */ - public static void copyInputToOutput( - InputStream input, - OutputStream output) - throws IOException { - BufferedInputStream in = new BufferedInputStream(input); - BufferedOutputStream out = new BufferedOutputStream(output); - byte buffer[] = new byte[8192]; - for (int count = 0; count != -1;) { - count = in.read(buffer, 0, 8192); - if (count != -1) - out.write(buffer, 0, count); - } - - try { - in.close(); - out.close(); - } catch (IOException ex) { - throw new IOException("Closing file streams, " + ex.getMessage()); - } - } - - - /** - * Replaces occurences of non-alphanumeric characters with a supplied char. - */ - public static String replaceNonAlphanumeric(String str, char subst) { - StringBuffer ret = new StringBuffer(str.length()); - char[] testChars = str.toCharArray(); - for (int i = 0; i < testChars.length; i++) { - if (Character.isLetterOrDigit(testChars[i])) { - ret.append(testChars[i]); - } else { - ret.append( subst ); - } - } - return ret.toString(); - } - - /** - * Convert string to string array. - */ - public static String[] stringToStringArray(String instr, String delim) - throws NoSuchElementException, NumberFormatException { - StringTokenizer toker = new StringTokenizer(instr, delim); - String stringArray[] = new String[toker.countTokens()]; - int i = 0; - while (toker.hasMoreTokens()) { - stringArray[i++] = toker.nextToken(); - } - return stringArray; - } - - /** - * Convert string array to string. - */ - public static String stringArrayToString(String[] stringArray, String delim) { - String ret = ""; - for (int i = 0; i < stringArray.length; i++) { - if (ret.length() > 0) - ret = ret + delim + stringArray[i]; - else - ret = stringArray[i]; - } - return ret; - } - - - static Pattern absoluteURIPattern = Pattern.compile("^[a-z0-9]*:.*$"); - - private static boolean isAbsoluteURI(String uri) { - return absoluteURIPattern.matcher(uri).find(); - } - - private static boolean isRelativeURI(String uri) { - return !isAbsoluteURI(uri); - } - - /** - * } - * Resolve URI based considering xml:base and baseURI. - * @param baseURI Base URI of feed - * @param parent Parent from which to consider xml:base - * @param url URL to be resolved - */ - private static String resolveURI(String baseURI, Parent parent, String url) { - if (isRelativeURI(url)) { - url = (!".".equals(url) && !"./".equals(url)) ? url : ""; - - // Relative URI with parent - if (parent != null && parent instanceof Element) { - - // Do we have an xml:base? - String xmlbase = ((Element)parent).getAttributeValue( - "base", Namespace.XML_NAMESPACE); - if (xmlbase != null && xmlbase.trim().length() > 0) { - if (isAbsoluteURI(xmlbase)) { - // Absolute xml:base, so form URI right now - if (url.startsWith("/")) { - // Host relative URI - int slashslash = xmlbase.indexOf("//"); - int nextslash = xmlbase.indexOf("/", slashslash + 2); - if (nextslash != -1) xmlbase = xmlbase.substring(0, nextslash); - return formURI(xmlbase, url); - } - if (!xmlbase.endsWith("/")) { - // Base URI is filename, strip it off - xmlbase = xmlbase.substring(0, xmlbase.lastIndexOf("/")); - } - return formURI(xmlbase, url); - } else { - // Relative xml:base, so walk up tree - return resolveURI(baseURI, parent.getParent(), - stripTrailingSlash(xmlbase) + "/"+ stripStartingSlash(url)); - } - } - // No xml:base so walk up tree - return resolveURI(baseURI, parent.getParent(), url); - - // Relative URI with no parent (i.e. top of tree), so form URI right now - } else if (parent == null || parent instanceof Document) { - return formURI(baseURI, url); - } - } - return url; - } - - /** - * Form URI by combining base with append portion and giving - * special consideration to append portions that begin with ".." - * @param base Base of URI, may end with trailing slash - * @param append String to append, may begin with slash or ".." - */ - private static String formURI(String base, String append) { - base = stripTrailingSlash(base); - append = stripStartingSlash(append); - if (append.startsWith("..")) { - String ret = null; - String[] parts = append.split("/"); - for (int i=0; i