/*
* JBoss, a division of Red Hat
* Copyright 2006, Red Hat Middleware, LLC, and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.identity.idm.impl.repository;
import org.jboss.identity.idm.spi.repository.IdentityStoreRepository;
import org.jboss.identity.idm.spi.store.IdentityStore;
import org.jboss.identity.idm.spi.store.AttributeStore;
import org.jboss.identity.idm.spi.store.IdentityStoreInvocationContext;
import org.jboss.identity.idm.spi.model.IdentityObjectType;
import org.jboss.identity.idm.spi.model.IdentityObject;
import org.jboss.identity.idm.spi.configuration.metadata.IdentityRepositoryConfigurationMetaData;
import org.jboss.identity.idm.spi.configuration.metadata.IdentityStoreMappingMetaData;
import org.jboss.identity.idm.spi.configuration.IdentityRepositoryConfigurationContext;
import org.jboss.identity.idm.spi.cache.IdentityStoreCacheProvider;
import org.jboss.identity.idm.common.exception.IdentityException;
import org.jboss.identity.idm.impl.helper.SecurityActions;
import org.jboss.identity.idm.impl.cache.JBossCacheIdentityStoreWrapper;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.List;
import java.util.HashMap;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
/**
* @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
* @version : 0.1 $
*/
public abstract class AbstractIdentityStoreRepository implements IdentityStoreRepository, Serializable
{
protected Map<String, IdentityStore> identityStoreMappings = new HashMap<String, IdentityStore>();
protected Map<String, AttributeStore> attributeStoreMappings = new HashMap<String, AttributeStore>();
protected IdentityStore defaultIdentityStore;
protected AttributeStore defaultAttributeStore;
protected IdentityRepositoryConfigurationContext configurationContext;
public static final String CACHE_OPTION = "cache";
public static final String CACHE_CONFIG_FILE_OPTION = "cache.config-file";
public static final String CACHE_PROVIDER_CLASS_OPTION = "cache.provider.class";
public static final String ALLOW_NOT_DEFINED_IDENTITY_OBJECT_TYPES_OPTION = "allowNotDefinedIdentityObjectTypes";
private boolean allowNotDefinedIdentityObjectTypes = false;
public void bootstrap(IdentityRepositoryConfigurationContext configurationContext,
Map<String, IdentityStore> bootstrappedIdentityStores,
Map<String, AttributeStore> bootstrappedAttributeStores) throws IdentityException
{
this.configurationContext = configurationContext;
IdentityRepositoryConfigurationMetaData configurationMD = configurationContext.getRepositoryConfigurationMetaData();
String asId = configurationMD.getDefaultAttributeStoreId();
String isId = configurationMD.getDefaultIdentityStoreId();
if (asId != null && bootstrappedAttributeStores.keySet().contains(asId))
{
defaultAttributeStore = bootstrappedAttributeStores.get(asId);
//TODO: cache wrap support
}
String allowNotDefinedIOT = configurationMD.getOptionSingleValue(ALLOW_NOT_DEFINED_IDENTITY_OBJECT_TYPES_OPTION);
if (allowNotDefinedIOT != null && allowNotDefinedIOT.equalsIgnoreCase("true"))
{
this.allowNotDefinedIdentityObjectTypes = true;
}
if (isId != null && bootstrappedIdentityStores.keySet().contains(isId))
{
defaultIdentityStore = bootstrappedIdentityStores.get(isId);
String cacheOption = configurationMD.getOptionSingleValue(CACHE_OPTION);
if (cacheOption != null && cacheOption.equalsIgnoreCase("true"))
{
String cacheConfig = configurationMD.getOptionSingleValue(CACHE_CONFIG_FILE_OPTION);
String cacheSupportClass = configurationMD.getOptionSingleValue(CACHE_PROVIDER_CLASS_OPTION);
if (cacheConfig == null)
{
throw new IdentityException(CACHE_CONFIG_FILE_OPTION + " is missing in the repository configuration");
}
if (cacheSupportClass == null)
{
throw new IdentityException(CACHE_PROVIDER_CLASS_OPTION + " is missing in the repository configuration");
}
ClassLoader classLoader = SecurityActions.getContextClassLoader();
InputStream cacheConfigInputStream = classLoader.getResourceAsStream(cacheConfig);
if (cacheConfigInputStream == null)
{
throw new IdentityException("JBoss Cache config file specified in option \"" + CACHE_CONFIG_FILE_OPTION +
"\" doesn't exist: " + cacheConfig);
}
try
{
Class cacheClass = null;
cacheClass = Class.forName(cacheSupportClass);
Class partypes[] = new Class[1];
partypes[0] = InputStream.class;
Constructor ct = cacheClass.getConstructor(partypes);
Object argList[] = new Object[1];
argList[0] = cacheConfigInputStream;
IdentityStoreCacheProvider cacheSupport = (IdentityStoreCacheProvider)ct.newInstance(argList);
defaultIdentityStore = new JBossCacheIdentityStoreWrapper(defaultIdentityStore, cacheSupport);
}
catch (Exception e)
{
throw new IdentityException("Cannot instantiate cache provider:" + cacheSupportClass, e);
}
}
}
for (IdentityStoreMappingMetaData identityStoreMappingMetaData : configurationMD.getIdentityStoreToIdentityObjectTypeMappings())
{
String storeId = identityStoreMappingMetaData.getIdentityStoreId();
List<String> identityObjectTypeMappings = identityStoreMappingMetaData.getIdentityObjectTypeMappings();
IdentityStore store = bootstrappedIdentityStores.get(storeId);
String cacheOption = identityStoreMappingMetaData.getOptionSingleValue(CACHE_OPTION);
if (cacheOption != null && cacheOption.equalsIgnoreCase("true"))
{
String cacheConfig = identityStoreMappingMetaData.getOptionSingleValue(CACHE_CONFIG_FILE_OPTION);
String cacheSupportClass = identityStoreMappingMetaData.getOptionSingleValue(CACHE_PROVIDER_CLASS_OPTION);
if (cacheConfig == null)
{
throw new IdentityException(CACHE_CONFIG_FILE_OPTION + " is missing in the repository identity-store-mapping configuration");
}
if (cacheSupportClass == null)
{
throw new IdentityException(CACHE_PROVIDER_CLASS_OPTION + " is missing in the repository configuration");
}
ClassLoader classLoader = SecurityActions.getContextClassLoader();
InputStream cacheConfigInputStream = classLoader.getResourceAsStream(cacheConfig);
if (cacheConfigInputStream == null)
{
throw new IdentityException("JBoss Cache config file specified in option \"" + CACHE_CONFIG_FILE_OPTION +
"\" doesn't exist: " + cacheConfig);
}
try
{
Class cacheClass = null;
cacheClass = Class.forName(cacheSupportClass);
Class partypes[] = new Class[1];
partypes[0] = InputStream.class;
Constructor ct = cacheClass.getConstructor(partypes);
Object argList[] = new Object[1];
argList[0] = cacheConfigInputStream;
IdentityStoreCacheProvider cacheSupport = (IdentityStoreCacheProvider)ct.newInstance(argList);
store = new JBossCacheIdentityStoreWrapper(store, cacheSupport);
}
catch (Exception e)
{
throw new IdentityException("Cannot instantiate cache provider:" + cacheSupportClass, e);
}
}
if (store == null)
{
throw new IdentityException("Mapped IdentityStore not available: " + storeId);
}
for (String mapping : identityObjectTypeMappings)
{
identityStoreMappings.put(mapping, store);
attributeStoreMappings.put(mapping, store);
}
}
}
public Set<IdentityStore> getConfiguredIdentityStores()
{
return new HashSet<IdentityStore>(identityStoreMappings.values());
}
public Set<AttributeStore> getConfiguredAttributeStores()
{
return new HashSet<AttributeStore>(attributeStoreMappings.values());
}
public Map<String, IdentityStore> getIdentityStoreMappings()
{
return identityStoreMappings;
}
public Map<String, AttributeStore> getAttributeStoreMappings()
{
return attributeStoreMappings;
}
public IdentityStore getIdentityStore(IdentityObjectType identityObjectType) throws IdentityException
{
IdentityStore store = identityStoreMappings.get(identityObjectType.getName());
if (store == null)
{
String option = configurationContext.getRepositoryConfigurationMetaData().getOptionSingleValue(ALLOW_NOT_DEFINED_IDENTITY_OBJECT_TYPES_OPTION);
if (option != null && option.equalsIgnoreCase("true"))
{
return defaultIdentityStore;
}
else
{
throw new IdentityException("IdentityObjectType not mapped in the configuration: " + identityObjectType);
}
}
return store;
}
public AttributeStore getAttributeStore(IdentityObjectType identityObjectType) throws IdentityException
{
AttributeStore store = attributeStoreMappings.get(identityObjectType.getName());
if (store == null)
{
String option = configurationContext.getRepositoryConfigurationMetaData().getOptionSingleValue(ALLOW_NOT_DEFINED_IDENTITY_OBJECT_TYPES_OPTION);
if (option != null && option.equalsIgnoreCase("true"))
{
return defaultIdentityStore;
}
else
{
throw new IdentityException("IdentityObjectType not mapped in the configuration: " + identityObjectType);
}
}
return store;
}
protected boolean hasIdentityObject(IdentityStoreInvocationContext ctx, IdentityStore is, IdentityObject io) throws IdentityException
{
try
{
if (is.findIdentityObject(ctx, io.getName(), io.getIdentityType()) != null)
{
return true;
}
}
catch (IdentityException e)
{
//store may throw exception if there is no identity so do nothing
//TODO: should have isIdentityPresent method
}
return false;
}
public boolean isAllowNotDefinedIdentityObjectTypes()
{
return allowNotDefinedIdentityObjectTypes;
}
}