You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2011/07/18 23:20:52 UTC
svn commit: r1148054 - in /chemistry/opencmis/trunk:
chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/
chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/ja...
Author: fmui
Date: Mon Jul 18 21:20:50 2011
New Revision: 1148054
URL: http://svn.apache.org/viewvc?rev=1148054&view=rev
Log:
CMIS-366: added cookie support
standard authentication provider clean up
Added:
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java (with props)
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java (with props)
Removed:
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/CookieAwareStandardAuthenticationProvider.java-6
Modified:
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/CmisBindingImpl.java
chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java
chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/SessionParameter.java
chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/LoginDialog.java
chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/model/ClientSession.java
Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/CmisBindingImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/CmisBindingImpl.java?rev=1148054&r1=1148053&r2=1148054&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/CmisBindingImpl.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/impl/CmisBindingImpl.java Mon Jul 18 21:20:50 2011
@@ -85,12 +85,12 @@ public class CmisBindingImpl implements
if (authenticationProvider == null) {
// create authentication provider and add it session
- String authProvider = sessionParameters.get(SessionParameter.AUTHENTICATION_PROVIDER_CLASS);
- if (authProvider != null) {
+ String authProviderClassName = sessionParameters.get(SessionParameter.AUTHENTICATION_PROVIDER_CLASS);
+ if (authProviderClassName != null) {
Object authProviderObj = null;
try {
- authProviderObj = Class.forName(authProvider).newInstance();
+ authProviderObj = Class.forName(authProviderClassName).newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Could not load authentication provider: " + e, e);
}
@@ -99,20 +99,8 @@ public class CmisBindingImpl implements
throw new IllegalArgumentException(
"Authentication provider does not implement AuthenticationProvider!");
}
-
- session.put(CmisBindingsHelper.AUTHENTICATION_PROVIDER_OBJECT, (AuthenticationProvider) authProviderObj);
-
- if (authProviderObj instanceof SessionAwareAuthenticationProvider) {
- ((SessionAwareAuthenticationProvider) authProviderObj).setSession(session);
- }
- }
- } else {
- session.put(CmisBindingsHelper.AUTHENTICATION_PROVIDER_OBJECT, authenticationProvider);
-
- if (authenticationProvider instanceof SessionAwareAuthenticationProvider) {
- ((SessionAwareAuthenticationProvider) authenticationProvider).setSession(session);
+ authenticationProvider = (AuthenticationProvider) authProviderObj;
}
-
}
// locale
@@ -148,6 +136,14 @@ public class CmisBindingImpl implements
// set up repository service
repositoryServiceWrapper = new RepositoryServiceImpl(session);
+
+ // add authentication provider to session
+ if (authenticationProvider != null) {
+ session.put(CmisBindingsHelper.AUTHENTICATION_PROVIDER_OBJECT, authenticationProvider);
+ if (authenticationProvider instanceof SessionAwareAuthenticationProvider) {
+ ((SessionAwareAuthenticationProvider) authenticationProvider).setSession(session);
+ }
+ }
}
public RepositoryService getRepositoryService() {
Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java?rev=1148054&r1=1148053&r2=1148054&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/StandardAuthenticationProvider.java Mon Jul 18 21:20:50 2011
@@ -29,8 +29,9 @@ import java.util.TimeZone;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import org.apache.chemistry.opencmis.client.bindings.spi.cookies.CmisCookieManager;
import org.apache.chemistry.opencmis.commons.SessionParameter;
-import org.apache.commons.codec.binary.Base64;
+import org.apache.chemistry.opencmis.commons.impl.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -47,53 +48,52 @@ public class StandardAuthenticationProvi
private static final String WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
+ private boolean sendBasicAuth;
+ private boolean sendUsernameToken;
+ private CmisCookieManager cookieManager;
+
@Override
- public Map<String, List<String>> getHTTPHeaders(String url) {
- Map<String, List<String>> result = null;
+ public void setSession(BindingSession session) {
+ super.setSession(session);
- // only send HTTP header if configured
- if (!isTrue(SessionParameter.AUTH_HTTP_BASIC)) {
- return null;
- }
+ sendBasicAuth = isTrue(SessionParameter.AUTH_HTTP_BASIC);
+ sendUsernameToken = isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN);
- result = new HashMap<String, List<String>>();
+ if (isTrue(SessionParameter.COOKIES)) {
+ cookieManager = new CmisCookieManager();
+ }
+ }
- // get user and password
- String user = getUser();
- String password = getPassword();
+ @Override
+ public Map<String, List<String>> getHTTPHeaders(String url) {
+ Map<String, List<String>> result = new HashMap<String, List<String>>();
- // if no user is set, don't set HTTP header
- if (user != null) {
- if (password == null) {
- password = "";
+ // authentication
+ if (sendBasicAuth) {
+ // get user and password
+ String user = getUser();
+ String password = getPassword();
+
+ // if no user is set, don't set basic auth header
+ if (user != null) {
+ result.put("Authorization", createBasicAuthHeaderValue(user, password));
}
- try {
- String authHeader = "Basic "
- + new String(Base64.encodeBase64((user + ":" + password).getBytes("ISO-8859-1")), "ISO-8859-1");
- result.put("Authorization", Collections.singletonList(authHeader));
- } catch (UnsupportedEncodingException e) {
- // shouldn't happen...
+ // get proxy user and password
+ String proxyUser = getProxyUser();
+ String proxyPassword = getProxyPassword();
+
+ // if no proxy user is set, don't set basic auth header
+ if (proxyUser != null) {
+ result.put("Proxy-Authorization", createBasicAuthHeaderValue(proxyUser, proxyPassword));
}
}
- // get proxy user and password
- String proxyUser = getProxyUser();
- String proxyPassword = getProxyPassword();
-
- // if no proxy user is set, don't set HTTP header
- if (proxyUser != null) {
- if (proxyPassword == null) {
- proxyPassword = "";
- }
-
- try {
- String authHeader = "Basic "
- + new String(Base64.encodeBase64((proxyUser + ":" + proxyPassword).getBytes("ISO-8859-1")),
- "ISO-8859-1");
- result.put("Proxy-Authorization", Collections.singletonList(authHeader));
- } catch (UnsupportedEncodingException e) {
- // shouldn't happen...
+ // cookies
+ if (cookieManager != null) {
+ Map<String, List<String>> cookies = cookieManager.get(url, result);
+ if (!cookies.isEmpty()) {
+ result.putAll(cookies);
}
}
@@ -101,16 +101,23 @@ public class StandardAuthenticationProvi
}
@Override
- public Element getSOAPHeaders(Object portObject) {
- // get user and password
- String user = getUser();
- String password = getPassword();
+ public void putResponseHeaders(String url, int statusCode, Map<String, List<String>> headers) {
+ if (cookieManager != null) {
+ cookieManager.put(url, headers);
+ }
+ }
+ @Override
+ public Element getSOAPHeaders(Object portObject) {
// only send SOAP header if configured
- if (!isTrue(SessionParameter.AUTH_SOAP_USERNAMETOKEN)) {
+ if (!sendUsernameToken) {
return null;
}
+ // get user and password
+ String user = getUser();
+ String password = getPassword();
+
// if no user is set, don't create SOAP header
if (user == null) {
return null;
@@ -170,10 +177,28 @@ public class StandardAuthenticationProvi
}
/**
+ * Creates a basic authentication header value from a username and a
+ * password.
+ */
+ protected List<String> createBasicAuthHeaderValue(String username, String password) {
+ if (password == null) {
+ password = "";
+ }
+
+ try {
+ return Collections.singletonList("Basic "
+ + Base64.encodeBytes((username + ":" + password).getBytes("ISO-8859-1")));
+ } catch (UnsupportedEncodingException e) {
+ // shouldn't happen...
+ return Collections.emptyList();
+ }
+ }
+
+ /**
* Returns <code>true</code> if the given parameter exists in the session
* and is set to true, <code>false</code> otherwise.
*/
- private boolean isTrue(String parameterName) {
+ protected boolean isTrue(String parameterName) {
Object value = getSession().get(parameterName);
if (value instanceof Boolean) {
Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java?rev=1148054&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java Mon Jul 18 21:20:50 2011
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. 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.
+ */
+/*
+ * This class has been taken from Apache Harmony (http://harmony.apache.org/)
+ * and has been modified to work with OpenCMIS.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.cookies;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
+
+/**
+ * Cookie Manager.
+ *
+ * This implementation conforms to RFC 2965, section 3.3.
+ */
+public class CmisCookieManager implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private static final String VERSION_ZERO_HEADER = "Set-cookie";
+ private static final String VERSION_ONE_HEADER = "Set-cookie2";
+
+ private final CmisCookieStoreImpl store;
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+ /**
+ * Constructs a new cookie manager.
+ */
+ public CmisCookieManager() {
+ store = new CmisCookieStoreImpl();
+ }
+
+ /**
+ * Searchs and gets all cookies in the cache by the specified uri in the
+ * request header.
+ *
+ * @param uri
+ * the specified uri to search for
+ * @param requestHeaders
+ * a list of request headers
+ * @return a map that record all such cookies, the map is unchangeable
+ */
+ public Map<String, List<String>> get(String url, Map<String, List<String>> requestHeaders) {
+ if (url == null || requestHeaders == null) {
+ throw new IllegalArgumentException("URL or headers are null!");
+ }
+
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new CmisConnectionException(e.getMessage(), e);
+ }
+
+ lock.writeLock().lock();
+ try {
+ List<CmisHttpCookie> cookies = store.get(uri);
+ for (int i = 0; i < cookies.size(); i++) {
+ CmisHttpCookie cookie = cookies.get(i);
+ String uriPath = uri.getPath();
+ String cookiePath = cookie.getPath();
+ // if the uri's path does not path-match cookie's path, remove
+ // cookies from the list
+ if (cookiePath == null || uriPath.length() == 0 || !uriPath.startsWith(cookiePath)) {
+ cookies.remove(i);
+ }
+ }
+
+ return getCookieMap(cookies, requestHeaders);
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private static Map<String, List<String>> getCookieMap(List<CmisHttpCookie> cookies,
+ Map<String, List<String>> requestHeaders) {
+ HashMap<String, List<String>> map = new HashMap<String, List<String>>();
+ ArrayList<String> cookieStr = new ArrayList<String>();
+ // If all cookies are version 1, add a "$Version="1"" header
+ boolean versionOne = true;
+ for (CmisHttpCookie cookie : cookies) {
+ if (cookie.getVersion() == 0) {
+ versionOne = false;
+ break;
+ }
+ }
+ if (versionOne && !cookies.isEmpty()) {
+ cookieStr.add("$Version=\"1\"");
+ }
+ // add every cookie's string representation into map
+ for (CmisHttpCookie cookie : cookies) {
+ cookieStr.add(cookie.toString());
+ }
+
+ if (cookieStr.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ map.put("Cookie", cookieStr);
+ return map;
+ }
+
+ /**
+ * Sets cookies according to uri and responseHeaders
+ *
+ * @param uri
+ * the specified uri
+ * @param responseHeaders
+ * a list of request headers
+ * @throws IOException
+ * if some error of I/O operation occurs
+ */
+ public void put(String url, Map<String, List<String>> responseHeaders) {
+ if (url == null || responseHeaders == null) {
+ throw new IllegalArgumentException("URL or headers are null!");
+ }
+
+ URI uri;
+ try {
+ uri = new URI(url);
+ } catch (URISyntaxException e) {
+ throw new CmisConnectionException(e.getMessage(), e);
+ }
+
+ lock.writeLock().lock();
+ try {
+ // parse and construct cookies according to the map
+ List<CmisHttpCookie> cookies = parseCookie(responseHeaders);
+ for (CmisHttpCookie cookie : cookies) {
+ if (cookie.getDomain() == null) {
+ cookie.setDomain(uri.getHost());
+ }
+ if (cookie.getPath() == null) {
+ cookie.setPath("/");
+ }
+ store.add(uri, cookie);
+ }
+ } finally {
+ lock.writeLock().unlock();
+ }
+ }
+
+ private static List<CmisHttpCookie> parseCookie(Map<String, List<String>> responseHeaders) {
+ List<CmisHttpCookie> cookies = new ArrayList<CmisHttpCookie>();
+ for (Map.Entry<String, List<String>> entry : responseHeaders.entrySet()) {
+ String key = entry.getKey();
+ // Only "Set-cookie" and "Set-cookie2" pair will be parsed
+ if (key != null && (key.equalsIgnoreCase(VERSION_ZERO_HEADER) || key.equalsIgnoreCase(VERSION_ONE_HEADER))) {
+ // parse list elements one by one
+ for (String cookieStr : entry.getValue()) {
+ try {
+ for (CmisHttpCookie cookie : CmisHttpCookie.parse(cookieStr)) {
+ cookies.add(cookie);
+ }
+ } catch (IllegalArgumentException e) {
+ // this string is invalid, jump to the next one.
+ }
+ }
+ }
+ }
+
+ return cookies;
+ }
+
+ /**
+ * Gets current cookie store.
+ *
+ * @return the cookie store currently used by cookie manager.
+ */
+ public CmisCookieStoreImpl getCookieStore() {
+ return store;
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java?rev=1148054&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java Mon Jul 18 21:20:50 2011
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. 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.
+ */
+/*
+ * This class has been taken from Apache Harmony (http://harmony.apache.org/)
+ * and has been modified to work with OpenCMIS.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.cookies;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides an in-memory cookie store.
+ */
+class CmisCookieStoreImpl implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Map<URI, ArrayList<CmisHttpCookie>> storeMap = new HashMap<URI, ArrayList<CmisHttpCookie>>();
+
+ public void add(URI uri, CmisHttpCookie cookie) {
+ if (uri == null || cookie == null) {
+ throw new NullPointerException();
+ }
+
+ ArrayList<CmisHttpCookie> cookies;
+ if (storeMap.containsKey(uri)) {
+ cookies = storeMap.get(uri);
+ cookies.remove(cookie);
+ cookies.add(cookie);
+ } else {
+ cookies = new ArrayList<CmisHttpCookie>();
+ cookies.add(cookie);
+ storeMap.put(uri, cookies);
+ }
+ }
+
+ public List<CmisHttpCookie> get(URI uri) {
+ if (uri == null) {
+ throw new NullPointerException("URI is null!");
+ }
+
+ // get cookies associated with given URI. If none, returns an empty list
+ List<CmisHttpCookie> cookies = storeMap.get(uri);
+ if (cookies == null) {
+ cookies = new ArrayList<CmisHttpCookie>();
+ } else {
+ // eliminate expired cookies
+ for (CmisHttpCookie cookie : cookies) {
+ if (cookie.hasExpired()) {
+ cookies.remove(cookie);
+ }
+ }
+ }
+
+ // get cookies whose domain matches the given URI
+ Set<URI> uris = storeMap.keySet();
+ for (URI u : uris) {
+ // exclude the given URI
+ if (!u.equals(uri)) {
+ List<CmisHttpCookie> listCookie = storeMap.get(u);
+ for (CmisHttpCookie cookie : listCookie) {
+ if (CmisHttpCookie.domainMatches(cookie.getDomain(), uri.getHost())) {
+ if (cookie.hasExpired()) {
+ listCookie.remove(cookie);
+ } else if (!(cookie.hasExpired() || cookies.contains(cookie))) {
+ cookies.add(cookie);
+ }
+ }
+ }
+ }
+ }
+
+ return cookies;
+ }
+
+ public List<CmisHttpCookie> getCookies() {
+ List<CmisHttpCookie> cookies = new ArrayList<CmisHttpCookie>();
+ Collection<ArrayList<CmisHttpCookie>> values = storeMap.values();
+ for (ArrayList<CmisHttpCookie> list : values) {
+ for (CmisHttpCookie cookie : list) {
+ if (cookie.hasExpired()) {
+ list.remove(cookie); // eliminate expired cookies
+ } else if (!cookies.contains(cookie)) {
+ cookies.add(cookie);
+ }
+ }
+ }
+
+ return Collections.unmodifiableList(cookies);
+ }
+
+ public List<URI> getURIs() {
+ return new ArrayList<URI>(storeMap.keySet());
+ }
+
+ public boolean remove(URI uri, CmisHttpCookie cookie) {
+ if (cookie == null) {
+ throw new NullPointerException("Cookie is null!");
+ }
+
+ boolean success = false;
+ Collection<ArrayList<CmisHttpCookie>> values = storeMap.values();
+ for (ArrayList<CmisHttpCookie> list : values) {
+ if (list.remove(cookie)) {
+ success = true;
+ }
+ }
+
+ return success;
+ }
+
+ public boolean removeAll() {
+ if (!storeMap.isEmpty()) {
+ storeMap.clear();
+ }
+
+ return true;
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisCookieStoreImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java?rev=1148054&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java Mon Jul 18 21:20:50 2011
@@ -0,0 +1,790 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. 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.
+ */
+/*
+ * This class has been taken from Apache Harmony (http://harmony.apache.org/)
+ * and has been modified to work with OpenCMIS.
+ */
+package org.apache.chemistry.opencmis.client.bindings.spi.cookies;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class represents a http cookie, which indicates the status information
+ * between the client agent side and the server side. According to RFC, there
+ * are 3 http cookie specifications. This class is compatible with all the three
+ * forms. HttpCookie class can accept all these 3 forms of syntax.
+ */
+public final class CmisHttpCookie implements Cloneable, Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final String DOT_STR = ".";
+ private static final String LOCAL_STR = ".local";
+ private static final String QUOTE_STR = "\"";
+ private static final String COMMA_STR = ",";
+ private static Pattern HEAD_PATTERN = Pattern.compile("Set-Cookie2?:", Pattern.CASE_INSENSITIVE);
+ private static Pattern NAME_PATTERN = Pattern.compile(
+ "([^$=,\u0085\u2028\u2029][^,\n\t\r\r\n\u0085\u2028\u2029]*?)=([^;]*)(;)?", Pattern.DOTALL
+ | Pattern.CASE_INSENSITIVE);
+ private static Pattern ATTR_PATTERN0 = Pattern.compile("([^;=]*)(?:=([^;]*))?");
+ private static Pattern ATTR_PATTERN1 = Pattern.compile("(,?[^;=]*)(?:=([^;,]*))?((?=.))?");
+
+ private abstract static class Setter {
+ boolean set;
+
+ Setter() {
+ set = false;
+ }
+
+ boolean isSet() {
+ return set;
+ }
+
+ void set(boolean isSet) {
+ set = isSet;
+ }
+
+ abstract void setValue(String value, CmisHttpCookie cookie);
+
+ void validate(String value, CmisHttpCookie cookie) {
+ if (cookie.getVersion() == 1 && value != null && value.contains(COMMA_STR)) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ private HashMap<String, Setter> attributeSet = new HashMap<String, Setter>();
+
+ /**
+ * A utility method used to check whether the host name is in a domain or
+ * not.
+ *
+ * @param domain
+ * the domain to be checked against
+ * @param host
+ * the host to be checked
+ * @return true if the host is in the domain, false otherwise
+ */
+ public static boolean domainMatches(String domain, String host) {
+ if (domain == null || host == null) {
+ return false;
+ }
+ String newDomain = domain.toLowerCase();
+ String newHost = host.toLowerCase();
+ return isValidDomain(newDomain) && effDomainMatches(newDomain, newHost) && isValidHost(newDomain, newHost);
+ }
+
+ private static boolean effDomainMatches(String domain, String host) {
+ // calculate effective host name
+ String effHost = host.indexOf(DOT_STR) != -1 ? host : (host + LOCAL_STR);
+
+ // Rule 2: domain and host are string-compare equal, or A = NB, B = .B'
+ // and N is a non-empty name string
+ boolean inDomain = domain.equals(effHost);
+ inDomain = inDomain
+ || (effHost.endsWith(domain) && effHost.length() > domain.length() && domain.startsWith(DOT_STR));
+
+ return inDomain;
+ }
+
+ private static boolean isCommaDelim(CmisHttpCookie cookie) {
+ String value = cookie.getValue();
+ if (value.startsWith(QUOTE_STR) && value.endsWith(QUOTE_STR)) {
+ cookie.setValue(value.substring(1, value.length() - 1));
+ return false;
+ }
+
+ if (cookie.getVersion() == 1 && value.contains(COMMA_STR)) {
+ cookie.setValue(value.substring(0, value.indexOf(COMMA_STR)));
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isValidDomain(String domain) {
+ // Rule 1: The value for Domain contains embedded dots, or is .local
+ if (domain.length() <= 2) {
+ return false;
+ }
+
+ return domain.substring(1, domain.length() - 1).indexOf(DOT_STR) != -1 || domain.equals(LOCAL_STR);
+ }
+
+ private static boolean isValidHost(String domain, String host) {
+ // Rule 3: host does not end with domain, or the remainder does not
+ // contain "."
+ boolean matches = !host.endsWith(domain);
+ if (!matches) {
+ String hostSub = host.substring(0, host.length() - domain.length());
+ matches = hostSub.indexOf(DOT_STR) == -1;
+ }
+
+ return matches;
+ }
+
+ /**
+ * Constructs a cookie from a string. The string should comply with
+ * set-cookie or set-cookie2 header format as specified in RFC 2965. Since
+ * set-cookies2 syntax allows more than one cookie definitions in one
+ * header, the returned object is a list.
+ *
+ * @param header
+ * a set-cookie or set-cookie2 header.
+ * @return a list of constructed cookies
+ * @throws IllegalArgumentException
+ * if the string does not comply with cookie specification, or
+ * the cookie name contains illegal characters, or reserved
+ * tokens of cookie specification appears
+ * @throws NullPointerException
+ * if header is null
+ */
+ public static List<CmisHttpCookie> parse(String header) {
+ Matcher matcher = HEAD_PATTERN.matcher(header);
+ // Parse cookie name & value
+ List<CmisHttpCookie> list = null;
+ CmisHttpCookie cookie = null;
+ String headerString = header;
+ int version = 0;
+ // process set-cookie | set-cookie2 head
+ if (matcher.find()) {
+ String cookieHead = matcher.group();
+ if ("set-cookie2:".equalsIgnoreCase(cookieHead)) {
+ version = 1;
+ }
+ headerString = header.substring(cookieHead.length());
+ }
+
+ // parse cookie name/value pair
+ matcher = NAME_PATTERN.matcher(headerString);
+ if (matcher.lookingAt()) {
+ list = new ArrayList<CmisHttpCookie>();
+ cookie = new CmisHttpCookie(matcher.group(1), matcher.group(2));
+ cookie.setVersion(version);
+
+ /*
+ * Comma is a delimiter in cookie spec 1.1. If find comma in version
+ * 1 cookie header, part of matched string need to be spitted out.
+ */
+ String nameGroup = matcher.group();
+ if (isCommaDelim(cookie)) {
+ headerString = headerString.substring(nameGroup.indexOf(COMMA_STR));
+ } else {
+ headerString = headerString.substring(nameGroup.length());
+ }
+ list.add(cookie);
+ } else {
+ throw new IllegalArgumentException();
+ }
+
+ // parse cookie headerString
+ while (!(headerString.length() == 0)) {
+ matcher = cookie.getVersion() == 1 ? ATTR_PATTERN1.matcher(headerString) : ATTR_PATTERN0
+ .matcher(headerString);
+
+ if (matcher.lookingAt()) {
+ String attrName = matcher.group(1).trim();
+
+ // handle special situation like: <..>;;<..>
+ if (attrName.length() == 0) {
+ headerString = headerString.substring(1);
+ continue;
+ }
+
+ // If port is the attribute, then comma will not be used as a
+ // delimiter
+ if (attrName.equalsIgnoreCase("port") || attrName.equalsIgnoreCase("expires")) {
+ int start = matcher.regionStart();
+ matcher = ATTR_PATTERN0.matcher(headerString);
+ matcher.region(start, headerString.length());
+ matcher.lookingAt();
+ } else if (cookie.getVersion() == 1 && attrName.startsWith(COMMA_STR)) {
+ // If the last encountered token is comma, and the parsed
+ // attribute is not port, then this attribute/value pair
+ // ends.
+ headerString = headerString.substring(1);
+ matcher = NAME_PATTERN.matcher(headerString);
+ if (matcher.lookingAt()) {
+ cookie = new CmisHttpCookie(matcher.group(1), matcher.group(2));
+ list.add(cookie);
+ headerString = headerString.substring(matcher.group().length());
+ continue;
+ }
+ }
+
+ Setter setter = cookie.attributeSet.get(attrName.toLowerCase());
+ if (null == setter) {
+ throw new IllegalArgumentException();
+ }
+ if (!setter.isSet()) {
+ String attrValue = matcher.group(2);
+ setter.validate(attrValue, cookie);
+ setter.setValue(matcher.group(2), cookie);
+ }
+ headerString = headerString.substring(matcher.end());
+ }
+ }
+
+ return list;
+ }
+
+ private String comment;
+ private String commentURL;
+ private boolean discard;
+ private String domain;
+ private long maxAge = -1l;
+ private String name;
+ private String path;
+ private String portList;
+ private boolean secure;
+ private String value;
+ private int version = 1;
+
+ {
+ attributeSet.put("comment", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setComment(value);
+ if (cookie.getComment() != null) {
+ set(true);
+ }
+ }
+ });
+ attributeSet.put("commenturl", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setCommentURL(value);
+ if (cookie.getCommentURL() != null) {
+ set(true);
+ }
+ }
+ });
+ attributeSet.put("discard", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setDiscard(true);
+ set(true);
+ }
+ });
+ attributeSet.put("domain", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setDomain(value);
+ if (cookie.getDomain() != null) {
+ set(true);
+ }
+ }
+ });
+ attributeSet.put("max-age", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ try {
+ cookie.setMaxAge(Long.parseLong(value));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid max-age!");
+ }
+ set(true);
+
+ if (!attributeSet.get("version").isSet()) {
+ cookie.setVersion(1);
+ }
+ }
+ });
+
+ attributeSet.put("path", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setPath(value);
+ if (cookie.getPath() != null) {
+ set(true);
+ }
+ }
+ });
+ attributeSet.put("port", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setPortlist(value);
+ if (cookie.getPortlist() != null) {
+ set(true);
+ }
+ }
+
+ @Override
+ void validate(String v, CmisHttpCookie cookie) {
+ return;
+ }
+ });
+ attributeSet.put("secure", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setSecure(true);
+ set(true);
+ }
+ });
+ attributeSet.put("version", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ try {
+ int v = Integer.parseInt(value);
+ if (v > cookie.getVersion()) {
+ cookie.setVersion(v);
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid version!");
+ }
+ if (cookie.getVersion() != 0) {
+ set(true);
+ }
+ }
+ });
+
+ attributeSet.put("expires", new Setter() {
+ @Override
+ void setValue(String value, CmisHttpCookie cookie) {
+ cookie.setVersion(0);
+ attributeSet.get("version").set(true);
+ if (!attributeSet.get("max-age").isSet()) {
+ attributeSet.get("max-age").set(true);
+ if (!"en".equalsIgnoreCase(Locale.getDefault().getLanguage())) {
+ cookie.setMaxAge(0);
+ return;
+ }
+ try {
+ cookie.setMaxAge((Date.parse(value) - System.currentTimeMillis()) / 1000);
+ } catch (IllegalArgumentException e) {
+ cookie.setMaxAge(0);
+ }
+ }
+ }
+
+ @Override
+ void validate(String v, CmisHttpCookie cookie) {
+ return;
+ }
+ });
+ }
+
+ /**
+ * Initializes a cookie with the specified name and value.
+ *
+ * The name attribute can just contain ASCII characters, which is immutable
+ * after creation. Commas, white space and semicolons are not allowed. The $
+ * character is also not allowed to be the beginning of the name.
+ *
+ * The value attribute depends on what the server side is interested. The
+ * setValue method can be used to change it.
+ *
+ * RFC 2965 is the default cookie specification of this class. If one wants
+ * to change the version of the cookie, the setVersion method is available.
+ *
+ * @param name
+ * - the specific name of the cookie
+ * @param value
+ * - the specific value of the cookie
+ *
+ * @throws IllegalArgumentException
+ * - if the name contains not-allowed or reserved characters
+ *
+ * @throws NullPointerException
+ * if the value of name is null
+ */
+ public CmisHttpCookie(String name, String value) {
+ String ntrim = name.trim(); // erase leading and trailing whitespaces
+ if (!isValidName(ntrim)) {
+ throw new IllegalArgumentException("Invalid name!");
+ }
+
+ this.name = ntrim;
+ this.value = value;
+ }
+
+ private void attrToString(StringBuilder builder, String attrName, String attrValue) {
+ if (attrValue != null && builder != null) {
+ builder.append(";");
+ builder.append("$");
+ builder.append(attrName);
+ builder.append("=\"");
+ builder.append(attrValue);
+ builder.append(QUOTE_STR);
+ }
+ }
+
+ /**
+ * Answers a copy of this object.
+ *
+ * @return a copy of this cookie
+ */
+ @Override
+ public Object clone() {
+ try {
+ CmisHttpCookie obj = (CmisHttpCookie) super.clone();
+ return obj;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Answers whether two cookies are equal. Two cookies are equal if they have
+ * the same domain and name in a case-insensitive mode and path in a
+ * case-sensitive mode.
+ *
+ * @param obj
+ * the object to be compared.
+ * @return true if two cookies equals, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof CmisHttpCookie) {
+ CmisHttpCookie anotherCookie = (CmisHttpCookie) obj;
+ if (name.equalsIgnoreCase(anotherCookie.getName())) {
+ String anotherDomain = anotherCookie.getDomain();
+ boolean equals = domain == null ? anotherDomain == null : domain.equalsIgnoreCase(anotherDomain);
+ if (equals) {
+ String anotherPath = anotherCookie.getPath();
+ return path == null ? anotherPath == null : path.equals(anotherPath);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Answers the value of comment attribute(specified in RFC 2965) of this
+ * cookie.
+ *
+ * @return the value of comment attribute
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * Answers the value of commentURL attribute(specified in RFC 2965) of this
+ * cookie.
+ *
+ * @return the value of commentURL attribute
+ */
+ public String getCommentURL() {
+ return commentURL;
+ }
+
+ /**
+ * Answers the value of discard attribute(specified in RFC 2965) of this
+ * cookie.
+ *
+ * @return discard value of this cookie
+ */
+ public boolean getDiscard() {
+ return discard;
+ }
+
+ /**
+ * Answers the domain name for this cookie in the format specified in RFC
+ * 2965
+ *
+ * @return the domain value of this cookie
+ */
+ public String getDomain() {
+ return domain;
+ }
+
+ /**
+ * Returns the Max-Age value as specified in RFC 2965 of this cookie.
+ *
+ * @return the Max-Age value
+ */
+ public long getMaxAge() {
+ return maxAge;
+ }
+
+ /**
+ * Answers the name for this cookie.
+ *
+ * @return the name for this cookie
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Answers the path part of a request URL to which this cookie is returned.
+ * This cookie is visible to all subpaths.
+ *
+ * @return the path used to return the cookie
+ */
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Answers the value of port attribute(specified in RFC 2965) of this
+ * cookie.
+ *
+ * @return port list of this cookie
+ */
+ public String getPortlist() {
+ return portList;
+ }
+
+ /**
+ * Answers true if the browser only sends cookies over a secure protocol.
+ * False if can send cookies through any protocols.
+ *
+ * @return true if sends cookies only through secure protocol, false
+ * otherwise
+ */
+ public boolean getSecure() {
+ return secure;
+ }
+
+ /**
+ * Answers the value of this cookie.
+ *
+ * @return the value of this cookie
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Get the version of this cookie
+ *
+ * @return 0 indicates the original Netscape cookie specification, while 1
+ * indicates RFC 2965/2109 specification.
+ */
+ public int getVersion() {
+ return version;
+ }
+
+ /**
+ * Answers whether the cookie has expired.
+ *
+ * @return true is the cookie has expired, false otherwise
+ */
+ public boolean hasExpired() {
+ // -1 indicates the cookie will persist until browser shutdown
+ // so the cookie is not expired.
+ if (maxAge == -1l) {
+ return false;
+ }
+
+ boolean expired = false;
+ if (maxAge <= 0l) {
+ expired = true;
+ }
+ return expired;
+ }
+
+ /**
+ * Answers hash code of this http cookie. The result is calculated as below:
+ *
+ * getName().toLowerCase().hashCode() + getDomain().toLowerCase().hashCode()
+ * + getPath().hashCode()
+ *
+ * @return the hash code of this cookie
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = name.toLowerCase().hashCode();
+ hashCode += domain == null ? 0 : domain.toLowerCase().hashCode();
+ hashCode += path == null ? 0 : path.hashCode();
+ return hashCode;
+ }
+
+ private boolean isValidName(String n) {
+ // name cannot be empty or begin with '$' or equals the reserved
+ // attributes (case-insensitive)
+ boolean isValid = !(n.length() == 0 || n.startsWith("$") || attributeSet.containsKey(n.toLowerCase()));
+ if (isValid) {
+ for (int i = 0; i < n.length(); i++) {
+ char nameChar = n.charAt(i);
+ // name must be ASCII characters and cannot contain ';', ',' and
+ // whitespace
+ if (nameChar < 0 || nameChar >= 127 || nameChar == ';' || nameChar == ','
+ || (Character.isWhitespace(nameChar) && nameChar != ' ')) {
+ isValid = false;
+ break;
+ }
+ }
+ }
+
+ return isValid;
+ }
+
+ /**
+ * Set the value of comment attribute(specified in RFC 2965) of this cookie.
+ *
+ * @param purpose
+ * the comment value to be set
+ */
+ public void setComment(String purpose) {
+ comment = purpose;
+ }
+
+ /**
+ * Set the value of commentURL attribute(specified in RFC 2965) of this
+ * cookie.
+ *
+ * @param purpose
+ * the value of commentURL attribute to be set
+ */
+ public void setCommentURL(String purpose) {
+ commentURL = purpose;
+ }
+
+ /**
+ * Set the value of discard attribute(specified in RFC 2965) of this cookie.
+ *
+ * @param discard
+ * the value for discard attribute
+ */
+ public void setDiscard(boolean discard) {
+ this.discard = discard;
+ }
+
+ /**
+ * Set the domain value for this cookie. Browsers send the cookie to the
+ * domain specified by this value. The form of the domain is specified in
+ * RFC 2965.
+ *
+ * @param pattern
+ * the domain pattern
+ */
+ public void setDomain(String pattern) {
+ domain = pattern == null ? null : pattern.toLowerCase();
+ }
+
+ /**
+ * Sets the Max-Age value as specified in RFC 2965 of this cookie to expire.
+ *
+ * @param expiry
+ * the value used to set the Max-Age value of this cookie
+ */
+ public void setMaxAge(long expiry) {
+ maxAge = expiry;
+ }
+
+ /**
+ * Set the path to which this cookie is returned. This cookie is visible to
+ * all the pages under the path and all subpaths.
+ *
+ * @param path
+ * the path to which this cookie is returned
+ */
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ /**
+ * Set the value of port attribute(specified in RFC 2965) of this cookie.
+ *
+ * @param ports
+ * the value for port attribute
+ */
+ public void setPortlist(String ports) {
+ portList = ports;
+ }
+
+ /*
+ * Handle 2 special cases: 1. value is wrapped by a quotation 2. value
+ * contains comma
+ */
+
+ /**
+ * Tells the browser whether the cookies should be sent to server through
+ * secure protocols.
+ *
+ * @param flag
+ * tells browser to send cookie to server only through secure
+ * protocol if flag is true
+ */
+ public void setSecure(boolean flag) {
+ secure = flag;
+ }
+
+ /**
+ * Sets the value for this cookie after it has been instantiated. String
+ * newValue can be in BASE64 form. If the version of the cookie is 0,
+ * special value as: white space, brackets, parentheses, equals signs,
+ * commas, double quotes, slashes, question marks, at signs, colons, and
+ * semicolons are not recommended. Empty values may lead to different
+ * behavior on different browsers.
+ *
+ * @param newValue
+ * the value for this cookie
+ */
+ public void setValue(String newValue) {
+ // FIXME: According to spec, version 0 cookie value does not allow many
+ // symbols. But RI does not implement it. Follow RI temporarily.
+ value = newValue;
+ }
+
+ /**
+ * Sets the version of the cookie. 0 indicates the original Netscape cookie
+ * specification, while 1 indicates RFC 2965/2109 specification.
+ *
+ * @param v
+ * 0 or 1 as stated above
+ * @throws IllegalArgumentException
+ * if v is neither 0 nor 1
+ */
+ public void setVersion(int v) {
+ if (v != 0 && v != 1) {
+ throw new IllegalArgumentException("Unknown version!");
+ }
+ version = v;
+ }
+
+ /**
+ * Returns a string to represent the cookie. The format of string follows
+ * the cookie specification. The leading token "Cookie" is not included
+ *
+ * @return the string format of the cookie object
+ */
+ @Override
+ public String toString() {
+ StringBuilder cookieStr = new StringBuilder();
+ cookieStr.append(name);
+ cookieStr.append("=");
+ if (version == 0) {
+ cookieStr.append(value);
+ } else if (version == 1) {
+ cookieStr.append(QUOTE_STR);
+ cookieStr.append(value);
+ cookieStr.append(QUOTE_STR);
+
+ attrToString(cookieStr, "Path", path);
+ attrToString(cookieStr, "Domain", domain);
+ attrToString(cookieStr, "Port", portList);
+ }
+
+ return cookieStr.toString();
+ }
+}
Propchange: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/cookies/CmisHttpCookie.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/SessionParameter.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/SessionParameter.java?rev=1148054&r1=1148053&r2=1148054&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/SessionParameter.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/SessionParameter.java Mon Jul 18 21:20:50 2011
@@ -75,7 +75,9 @@ public final class SessionParameter {
public static final String COMPRESSION = "org.apache.chemistry.opencmis.binding.compression";
public static final String CLIENT_COMPRESSION = "org.apache.chemistry.opencmis.binding.clientcompression";
-
+
+ public static final String COOKIES = "org.apache.chemistry.opencmis.binding.cookies";
+
public static final String CONNECT_TIMEOUT = "org.apache.chemistry.opencmis.binding.connecttimeout";
public static final String READ_TIMEOUT = "org.apache.chemistry.opencmis.binding.readtimeout";
Modified: chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/LoginDialog.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/LoginDialog.java?rev=1148054&r1=1148053&r2=1148054&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/LoginDialog.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/LoginDialog.java Mon Jul 18 21:20:50 2011
@@ -68,6 +68,8 @@ public class LoginDialog extends JDialog
public static final String SYSPROP_BINDING = ClientSession.WORKBENCH_PREFIX + "binding";
public static final String SYSPROP_AUTHENTICATION = ClientSession.WORKBENCH_PREFIX + "authentication";
public static final String SYSPROP_COMPRESSION = ClientSession.WORKBENCH_PREFIX + "compression";
+ public static final String SYSPROP_CLIENTCOMPRESSION = ClientSession.WORKBENCH_PREFIX + "clientcompression";
+ public static final String SYSPROP_COOKIES = ClientSession.WORKBENCH_PREFIX + "cookies";
public static final String SYSPROP_USER = ClientSession.WORKBENCH_PREFIX + "user";
public static final String SYSPROP_PASSWORD = ClientSession.WORKBENCH_PREFIX + "password";
@@ -89,6 +91,8 @@ public class LoginDialog extends JDialog
private JRadioButton compressionOffButton;
private JRadioButton clientCompressionOnButton;
private JRadioButton clientCompressionOffButton;
+ private JRadioButton cookiesOnButton;
+ private JRadioButton cookiesOffButton;
private JTextArea sessionParameterTextArea;
private JButton loadRepositoryButton;
private JButton loginButton;
@@ -137,7 +141,9 @@ public class LoginDialog extends JDialog
createClientCompressionButtons(basicPanel);
- makeCompactGrid(basicPanel, 7, 2, 5, 10, 5, 5);
+ createCookieButtons(basicPanel);
+
+ makeCompactGrid(basicPanel, 8, 2, 5, 10, 5, 5);
loginTabs.addTab("Basic", basicPanel);
@@ -334,7 +340,7 @@ public class LoginDialog extends JDialog
private void createCompressionButtons(Container pane) {
JPanel compressionContainer = new JPanel();
compressionContainer.setLayout(new BoxLayout(compressionContainer, BoxLayout.LINE_AXIS));
- boolean compression = !(System.getProperty(SYSPROP_BINDING, "compression").equalsIgnoreCase("off"));
+ boolean compression = !(System.getProperty(SYSPROP_COMPRESSION, "on").equalsIgnoreCase("off"));
compressionOnButton = new JRadioButton("On", compression);
compressionOffButton = new JRadioButton("Off", !compression);
ButtonGroup compressionGroup = new ButtonGroup();
@@ -352,7 +358,7 @@ public class LoginDialog extends JDialog
private void createClientCompressionButtons(Container pane) {
JPanel clientCompressionContainer = new JPanel();
clientCompressionContainer.setLayout(new BoxLayout(clientCompressionContainer, BoxLayout.LINE_AXIS));
- boolean clientCompression = (System.getProperty(SYSPROP_BINDING, "clientcompression").equalsIgnoreCase("on"));
+ boolean clientCompression = (System.getProperty(SYSPROP_CLIENTCOMPRESSION, "off").equalsIgnoreCase("on"));
clientCompressionOnButton = new JRadioButton("On", clientCompression);
clientCompressionOffButton = new JRadioButton("Off", !clientCompression);
ButtonGroup clientCompressionGroup = new ButtonGroup();
@@ -367,6 +373,24 @@ public class LoginDialog extends JDialog
pane.add(clientCompressionContainer);
}
+ private void createCookieButtons(Container pane) {
+ JPanel cookiesContainer = new JPanel();
+ cookiesContainer.setLayout(new BoxLayout(cookiesContainer, BoxLayout.LINE_AXIS));
+ boolean cookies = (System.getProperty(SYSPROP_COOKIES, "off").equalsIgnoreCase("on"));
+ cookiesOnButton = new JRadioButton("On", cookies);
+ cookiesOffButton = new JRadioButton("Off", !cookies);
+ ButtonGroup cookiesGroup = new ButtonGroup();
+ cookiesGroup.add(cookiesOnButton);
+ cookiesGroup.add(cookiesOffButton);
+ cookiesContainer.add(cookiesOnButton);
+ cookiesContainer.add(Box.createRigidArea(new Dimension(10, 0)));
+ cookiesContainer.add(cookiesOffButton);
+ JLabel cookiesLabel = new JLabel("Cookies:", JLabel.TRAILING);
+
+ pane.add(cookiesLabel);
+ pane.add(cookiesContainer);
+ }
+
private JButton createButton(String title) {
JButton button = new JButton(title);
button.setPreferredSize(new Dimension(Short.MAX_VALUE, 30));
@@ -440,7 +464,7 @@ public class LoginDialog extends JDialog
}
return ClientSession.createSessionParameters(url, binding, username, password, authentication,
- compressionOnButton.isSelected(), clientCompressionOnButton.isSelected());
+ compressionOnButton.isSelected(), clientCompressionOnButton.isSelected(), cookiesOnButton.isSelected());
}
private Map<String, String> createExpertSessionParameters() {
Modified: chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/model/ClientSession.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/model/ClientSession.java?rev=1148054&r1=1148053&r2=1148054&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/model/ClientSession.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/model/ClientSession.java Mon Jul 18 21:20:50 2011
@@ -102,7 +102,8 @@ public class ClientSession {
}
public static Map<String, String> createSessionParameters(String url, BindingType binding, String username,
- String password, Authentication authentication, boolean compression, boolean clientCompression) {
+ String password, Authentication authentication, boolean compression, boolean clientCompression,
+ boolean cookies) {
Map<String, String> parameters = new LinkedHashMap<String, String>();
if (binding == BindingType.WEBSERVICES) {
@@ -142,6 +143,10 @@ public class ClientSession {
parameters.put(SessionParameter.CLIENT_COMPRESSION, "true");
}
+ if (cookies) {
+ parameters.put(SessionParameter.COOKIES, "true");
+ }
+
// get additional workbench properties from system properties
Properties sysProps = System.getProperties();
for (String key : sysProps.stringPropertyNames()) {