Repository: cxf Updated Branches: refs/heads/3.0.x-fixes 345ccc219 -> d27c70ba0
[CXF-5886] Prototyping default OAuth2 Ehcache providers, to be tuned later on Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/d27c70ba Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/d27c70ba Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/d27c70ba Branch: refs/heads/3.0.x-fixes Commit: d27c70ba09faaead062bb554bb383a348919ecd9 Parents: 345ccc2 Author: Sergey Beryozkin <sberyoz...@talend.com> Authored: Mon Aug 18 18:12:36 2014 +0100 Committer: Sergey Beryozkin <sberyoz...@talend.com> Committed: Mon Aug 18 18:15:32 2014 +0100 ---------------------------------------------------------------------- rt/rs/security/oauth-parent/oauth2/pom.xml | 12 ++ .../AbstractAuthorizationCodeDataProvider.java | 6 +- .../code/DefaultEHCacheCodeDataProvider.java | 110 ++++++++++++ .../provider/AbstractOAuthDataProvider.java | 149 ++++++++++++++++ .../DefaultEHCacheOAuthDataProvider.java | 168 +++++++++++++++++++ .../rs/security/oauth2/utils/EHCacheUtil.java | 88 ++++++++++ 6 files changed, 531 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/pom.xml ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/pom.xml b/rt/rs/security/oauth-parent/oauth2/pom.xml index 11fa420..b221635 100644 --- a/rt/rs/security/oauth-parent/oauth2/pom.xml +++ b/rt/rs/security/oauth-parent/oauth2/pom.xml @@ -30,6 +30,11 @@ <version>3.0.2-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> + <properties> + <cxf.osgi.import> + net.sf.ehcache*;resolution:=optional;version="[2.5, 3.0.0)", + </cxf.osgi.import> + </properties> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> @@ -47,6 +52,13 @@ <scope>provided</scope> <optional>true</optional> </dependency> + <dependency> + <groupId>net.sf.ehcache</groupId> + <artifactId>ehcache</artifactId> + <version>${cxf.ehcache.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> <!--test dependencies--> <dependency> <groupId>org.apache.cxf</groupId> http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AbstractAuthorizationCodeDataProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AbstractAuthorizationCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AbstractAuthorizationCodeDataProvider.java index bb717fd..71f1002 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AbstractAuthorizationCodeDataProvider.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/AbstractAuthorizationCodeDataProvider.java @@ -21,6 +21,7 @@ package org.apache.cxf.rs.security.oauth2.grants.code; import java.util.List; +import org.apache.cxf.rs.security.oauth2.provider.AbstractOAuthDataProvider; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; @@ -28,9 +29,10 @@ import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; /** * Abstract AuthorizationCodeDataProvider implementation */ -public abstract class AbstractAuthorizationCodeDataProvider implements AuthorizationCodeDataProvider { +public abstract class AbstractAuthorizationCodeDataProvider + extends AbstractOAuthDataProvider implements AuthorizationCodeDataProvider { - private long grantLifetime; + private long grantLifetime = 3600L; public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java new file mode 100644 index 0000000..c4e261f --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/grants/code/DefaultEHCacheCodeDataProvider.java @@ -0,0 +1,110 @@ +/** + * 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. + */ +package org.apache.cxf.rs.security.oauth2.grants.code; + +import java.util.List; + +import net.sf.ehcache.Ehcache; + +import org.apache.cxf.Bus; +import org.apache.cxf.rs.security.oauth2.provider.DefaultEHCacheOAuthDataProvider; +import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; +import org.apache.cxf.rs.security.oauth2.utils.OAuthUtils; + +public class DefaultEHCacheCodeDataProvider extends DefaultEHCacheOAuthDataProvider + implements AuthorizationCodeDataProvider { + public static final String CODE_GRANT_CACHE_KEY = "cxf.oauth2.client.cache"; + + private long grantLifetime; + private Ehcache codeGrantCache; + + protected DefaultEHCacheCodeDataProvider() { + this(DEFAULT_CONFIG_URL, null); + } + + protected DefaultEHCacheCodeDataProvider(String configFileURL, Bus bus) { + this(configFileURL, bus, CODE_GRANT_CACHE_KEY, + CLIENT_CACHE_KEY, ACCESS_TOKEN_CACHE_KEY, REFRESH_TOKEN_CACHE_KEY); + } + + protected DefaultEHCacheCodeDataProvider(String configFileURL, + Bus bus, + String clientCacheKey, + String codeCacheKey, + String accessTokenKey, + String refreshTokenKey) { + super(configFileURL, bus, clientCacheKey, accessTokenKey, refreshTokenKey); + codeGrantCache = createCache(cacheManager, codeCacheKey); + } + + @Override + public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) + throws OAuthServiceException { + ServerAuthorizationCodeGrant grant = doCreateCodeGrant(reg); + saveAuthorizationGrant(grant); + return grant; + } + + @Override + public ServerAuthorizationCodeGrant removeCodeGrant(String code) throws OAuthServiceException { + ServerAuthorizationCodeGrant grant = getCacheValue(codeGrantCache, + code, + ServerAuthorizationCodeGrant.class); + if (grant != null) { + codeGrantCache.remove(code); + } + return grant; + } + + protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) + throws OAuthServiceException { + ServerAuthorizationCodeGrant grant = + new ServerAuthorizationCodeGrant(reg.getClient(), getCode(reg), getGrantLifetime(), getIssuedAt()); + grant.setApprovedScopes(getApprovedScopes(reg)); + grant.setAudience(reg.getAudience()); + grant.setClientCodeVerifier(reg.getClientCodeVerifier()); + grant.setSubject(reg.getSubject()); + grant.setRedirectUri(reg.getRedirectUri()); + return grant; + } + + protected List<String> getApprovedScopes(AuthorizationCodeRegistration reg) { + return reg.getApprovedScope(); + } + + protected String getCode(AuthorizationCodeRegistration reg) { + return OAuthUtils.generateRandomTokenKey(); + } + + public long getGrantLifetime() { + return grantLifetime; + } + + public void setGrantLifetime(long lifetime) { + this.grantLifetime = lifetime; + } + + protected long getIssuedAt() { + return OAuthUtils.getIssuedAt(); + } + + protected void saveAuthorizationGrant(ServerAuthorizationCodeGrant grant) { + putCacheValue(codeGrantCache, grant.getCode(), grant, grant.getExpiresIn()); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java new file mode 100644 index 0000000..915d87f --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/AbstractOAuthDataProvider.java @@ -0,0 +1,149 @@ +/** + * 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. + */ +package org.apache.cxf.rs.security.oauth2.provider; + +import java.util.Collections; +import java.util.List; + +import org.apache.cxf.rs.security.oauth2.common.AccessTokenRegistration; +import org.apache.cxf.rs.security.oauth2.common.Client; +import org.apache.cxf.rs.security.oauth2.common.OAuthPermission; +import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; +import org.apache.cxf.rs.security.oauth2.common.UserSubject; +import org.apache.cxf.rs.security.oauth2.tokens.bearer.BearerAccessToken; +import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; + +public abstract class AbstractOAuthDataProvider implements OAuthDataProvider { + private long accessTokenLifetime = 3600L; + private long refreshTokenLifetime = 360000L; + + protected AbstractOAuthDataProvider() { + } + + @Override + public ServerAccessToken createAccessToken(AccessTokenRegistration accessToken) + throws OAuthServiceException { + ServerAccessToken serverToken = doCreateAccessToken(accessToken); + saveAccessToken(serverToken); + return serverToken; + } + + @Override + public ServerAccessToken refreshAccessToken(Client client, String refreshTokenKey, + List<String> requestedScopes) throws OAuthServiceException { + RefreshToken oldRefreshToken = removeRefreshToken(client, refreshTokenKey); + + ServerAccessToken serverToken = doRefreshAccessToken(client, oldRefreshToken, requestedScopes); + saveAccessToken(serverToken); + return serverToken; + } + + @Override + public void revokeToken(Client client, String tokenKey, String tokenTypeHint) throws OAuthServiceException { + if (removeAccessToken(tokenKey)) { + return; + } + RefreshToken oldRefreshToken = removeRefreshToken(client, tokenKey); + if (oldRefreshToken != null) { + for (String accessTokenKey : oldRefreshToken.getAccessTokens()) { + removeAccessToken(accessTokenKey); + } + } + } + + @Override + public List<OAuthPermission> convertScopeToPermissions(Client client, + List<String> requestedScope) { + if (requestedScope.isEmpty()) { + return Collections.emptyList(); + } else { + throw new OAuthServiceException("Requested scopes can not be mapped to the permissions"); + } + } + + @Override + public ServerAccessToken getPreauthorizedToken(Client client, List<String> requestedScopes, + UserSubject subject, String grantType) + throws OAuthServiceException { + return null; + } + + protected ServerAccessToken doCreateAccessToken(AccessTokenRegistration accessToken) { + ServerAccessToken at = createNewAccessToken(accessToken.getClient()); + at.setAudience(accessToken.getAudience()); + at.setGrantType(accessToken.getGrantType()); + List<String> theScopes = accessToken.getApprovedScope(); + if (theScopes.isEmpty()) { + theScopes = accessToken.getRequestedScope(); + } + List<OAuthPermission> thePermissions = + convertScopeToPermissions(accessToken.getClient(), theScopes); + at.setScopes(thePermissions); + at.setSubject(accessToken.getSubject()); + createNewRefreshToken(at); + return at; + } + + protected ServerAccessToken createNewAccessToken(Client client) { + return new BearerAccessToken(client, accessTokenLifetime); + } + + protected RefreshToken createNewRefreshToken(ServerAccessToken at) { + RefreshToken rt = new RefreshToken(at.getClient(), refreshTokenLifetime); + rt.setAudience(at.getAudience()); + rt.setGrantType(at.getGrantType()); + rt.setScopes(at.getScopes()); + rt.getAccessTokens().add(at.getTokenKey()); + at.setRefreshToken(rt.getTokenKey()); + saveRefreshToken(rt); + return rt; + } + + protected ServerAccessToken doRefreshAccessToken(Client client, + RefreshToken oldRefreshToken, + List<String> requestedScopes) { + ServerAccessToken at = createNewAccessToken(client); + at.setAudience(oldRefreshToken.getAudience()); + at.setGrantType(oldRefreshToken.getGrantType()); + List<OAuthPermission> theNewScopes = convertScopeToPermissions(client, requestedScopes); + if (theNewScopes.isEmpty()) { + at.setScopes(oldRefreshToken.getScopes()); + } else if (oldRefreshToken.getScopes().containsAll(theNewScopes)) { + at.setScopes(theNewScopes); + } else { + throw new OAuthServiceException("Invalid scopes"); + } + createNewRefreshToken(at); + return at; + } + + public void setAccessTokenLifetime(long accessTokenLifetime) { + this.accessTokenLifetime = accessTokenLifetime; + } + + public void setRefreshTokenLifetime(long refreshTokenLifetime) { + this.refreshTokenLifetime = refreshTokenLifetime; + } + + protected abstract void saveAccessToken(ServerAccessToken serverToken); + protected abstract void saveRefreshToken(RefreshToken refreshToken); + protected abstract boolean removeAccessToken(String accessTokenKey); + protected abstract RefreshToken removeRefreshToken(Client client, String refreshTokenKey); + +} http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java new file mode 100644 index 0000000..4db4bbd --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/provider/DefaultEHCacheOAuthDataProvider.java @@ -0,0 +1,168 @@ +/** + * 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. + */ +package org.apache.cxf.rs.security.oauth2.provider; + +import java.io.File; +import java.net.URL; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; +import net.sf.ehcache.config.CacheConfiguration; +import net.sf.ehcache.config.Configuration; +import net.sf.ehcache.config.ConfigurationFactory; +import net.sf.ehcache.config.DiskStoreConfiguration; + +import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; +import org.apache.cxf.jaxrs.utils.ResourceUtils; +import org.apache.cxf.rs.security.oauth2.common.Client; +import org.apache.cxf.rs.security.oauth2.common.ServerAccessToken; +import org.apache.cxf.rs.security.oauth2.tokens.refresh.RefreshToken; +import org.apache.cxf.rs.security.oauth2.utils.EHCacheUtil; + +public class DefaultEHCacheOAuthDataProvider extends AbstractOAuthDataProvider { + public static final String CLIENT_CACHE_KEY = "cxf.oauth2.client.cache"; + public static final String ACCESS_TOKEN_CACHE_KEY = "cxf.oauth2.accesstoken.cache"; + public static final String REFRESH_TOKEN_CACHE_KEY = "cxf.oauth2.refreshtoken.cache"; + public static final String DEFAULT_CONFIG_URL = "cxf-oauth2-ehcache.xml"; + + protected CacheManager cacheManager; + private Ehcache clientCache; + private Ehcache accessTokenCache; + private Ehcache refreshTokenCache; + + public DefaultEHCacheOAuthDataProvider() { + this(DEFAULT_CONFIG_URL, null); + } + + public DefaultEHCacheOAuthDataProvider(String configFileURL, Bus bus) { + this(configFileURL, bus, CLIENT_CACHE_KEY, ACCESS_TOKEN_CACHE_KEY, REFRESH_TOKEN_CACHE_KEY); + } + + public DefaultEHCacheOAuthDataProvider(String configFileURL, + Bus bus, + String clientCacheKey, + String accessTokenKey, + String refreshTokenKey) { + createCaches(configFileURL, bus, clientCacheKey, accessTokenKey, refreshTokenKey); + } + + @Override + public Client getClient(String clientId) throws OAuthServiceException { + return getCacheValue(clientCache, clientId, Client.class); + } + + @Override + public ServerAccessToken getAccessToken(String accessToken) throws OAuthServiceException { + return getCacheValue(accessTokenCache, accessToken, ServerAccessToken.class); + } + + @Override + public void removeAccessToken(ServerAccessToken accessToken) throws OAuthServiceException { + removeAccessToken(accessToken.getTokenKey()); + } + + protected boolean removeAccessToken(String accessTokenKey) { + return accessTokenCache.remove(accessTokenKey); + } + + protected RefreshToken removeRefreshToken(Client client, String refreshTokenKey) { + RefreshToken refreshToken = getCacheValue(refreshTokenCache, refreshTokenKey, RefreshToken.class); + if (refreshToken != null) { + refreshTokenCache.remove(refreshTokenKey); + } + return refreshToken; + } + + protected void saveAccessToken(ServerAccessToken serverToken) { + putCacheValue(accessTokenCache, serverToken.getTokenKey(), serverToken, serverToken.getExpiresIn()); + } + + protected void saveRefreshToken(RefreshToken refreshToken) { + putCacheValue(refreshTokenCache, refreshToken.getTokenKey(), refreshToken, refreshToken.getExpiresIn()); + } + + protected static <T> T getCacheValue(Ehcache cache, String key, Class<T> cls) { + Element e = cache.get(key); + if (e != null) { + return cls.cast(e.getObjectValue()); + } else { + return null; + } + } + protected static void putCacheValue(Ehcache cache, String key, Object value, long ttl) { + Element element = new Element(key, value); + int parsedTTL = (int)ttl; + if (ttl != (long)parsedTTL) { + throw new OAuthServiceException("Requested time to live can not be supported"); + } + element.setTimeToLive(parsedTTL); + element.setTimeToIdle(parsedTTL); + cache.put(element); + } + + private static CacheManager createCacheManager(String configFile, Bus bus) { + if (bus == null) { + bus = BusFactory.getThreadDefaultBus(true); + } + + URL configFileURL = null; + try { + configFileURL = + ResourceUtils.getClasspathResourceURL(configFile, DefaultEHCacheOAuthDataProvider.class, bus); + } catch (Exception ex) { + // ignore + } + CacheManager cacheManager = null; + if (configFileURL == null) { + cacheManager = EHCacheUtil.createCacheManager(); + } else { + Configuration conf = ConfigurationFactory.parseConfiguration(configFileURL); + + if (bus != null) { + conf.setName(bus.getId()); + DiskStoreConfiguration dsc = conf.getDiskStoreConfiguration(); + if (dsc != null && "java.io.tmpdir".equals(dsc.getOriginalPath())) { + String path = conf.getDiskStoreConfiguration().getPath() + File.separator + + bus.getId(); + conf.getDiskStoreConfiguration().setPath(path); + } + } + + cacheManager = EHCacheUtil.createCacheManager(conf); + } + return cacheManager; + } + + protected static Ehcache createCache(CacheManager cacheManager, String cacheKey) { + CacheConfiguration clientCC = EHCacheUtil.getCacheConfiguration(cacheKey, cacheManager); + return cacheManager.addCacheIfAbsent(new Cache(clientCC)); + } + + private void createCaches(String configFile, Bus bus, + String clientCacheKey, String accessTokenKey, String refreshTokenKey) { + cacheManager = createCacheManager(configFile, bus); + + clientCache = createCache(cacheManager, clientCacheKey); + accessTokenCache = createCache(cacheManager, accessTokenKey); + refreshTokenCache = createCache(cacheManager, refreshTokenKey); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/d27c70ba/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EHCacheUtil.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EHCacheUtil.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EHCacheUtil.java new file mode 100644 index 0000000..adb160b --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/EHCacheUtil.java @@ -0,0 +1,88 @@ +/** + * 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. + */ + +package org.apache.cxf.rs.security.oauth2.utils; + +import java.lang.reflect.Method; + +import net.sf.ehcache.CacheException; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.config.CacheConfiguration; +import net.sf.ehcache.config.Configuration; + +/** + */ +public final class EHCacheUtil { + private static Method cacheManagerCreateMethodNoArg; + private static Method cacheManagerCreateMethodConfigurationArg; + static { + // these methods are either completely available or absent (valid assumption from 2.5.0 to 2.7.2 so far) + try { + // from 2.5.2 + cacheManagerCreateMethodNoArg = CacheManager.class.getMethod("newInstance", (Class<?>[])null); + cacheManagerCreateMethodConfigurationArg = CacheManager.class.getMethod("newInstance", Configuration.class); + } catch (NoSuchMethodException e) { + try { + // before 2.5.2 + cacheManagerCreateMethodNoArg = CacheManager.class.getMethod("create", (Class<?>[])null); + cacheManagerCreateMethodConfigurationArg = CacheManager.class.getMethod("create", Configuration.class); + } catch (Throwable t) { + // ignore + } + } + } + + private EHCacheUtil() { + // + } + + public static CacheConfiguration getCacheConfiguration(String key, CacheManager cacheManager) { + CacheConfiguration cc = cacheManager.getConfiguration().getCacheConfigurations().get(key); + if (cc == null && key.contains("-")) { + cc = cacheManager.getConfiguration().getCacheConfigurations().get( + key.substring(0, key.lastIndexOf('-') - 1)); + } + if (cc == null) { + cc = cacheManager.getConfiguration().getDefaultCacheConfiguration(); + } + if (cc == null) { + cc = new CacheConfiguration(); + } else { + cc = (CacheConfiguration)cc.clone(); + } + cc.setName(key); + return cc; + } + + public static CacheManager createCacheManager() throws CacheException { + try { + return (CacheManager)cacheManagerCreateMethodNoArg.invoke(null, (Object[])null); + } catch (Exception e) { + throw new CacheException(e); + } + } + + public static CacheManager createCacheManager(Configuration conf) throws CacheException { + try { + return (CacheManager)cacheManagerCreateMethodConfigurationArg.invoke(null, new Object[]{conf}); + } catch (Exception e) { + throw new CacheException(e); + } + } +}