/*****************************************************************************
* Copyright (c) 2008 g-Eclipse Consortium
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Mathias Stuempert - initial API and implementation
* Moritz Post - Changed the service mapping from awsAccessId/service
* to awsAuthToken/service. Improved singleton pattern.
*/
package eu.geclipse.aws.s3.internal;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import org.jets3t.service.S3Service;
import org.jets3t.service.S3ServiceException;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.security.AWSCredentials;
import eu.geclipse.aws.auth.AWSAuthToken;
import eu.geclipse.aws.auth.AWSAuthTokenDescription;
import eu.geclipse.aws.s3.IS3Constants;
import eu.geclipse.aws.s3.IS3Problems;
import eu.geclipse.core.auth.AbstractAuthTokenProvider;
import eu.geclipse.core.auth.AuthTokenRequest;
import eu.geclipse.core.auth.AuthenticationTokenManager;
import eu.geclipse.core.auth.IAuthenticationToken;
import eu.geclipse.core.reporting.ProblemException;
import eu.geclipse.core.security.ISecurityManager;
import eu.geclipse.core.security.ISecurityManagerListener;
/**
* Class that manages all instances of S3Services.
*/
public class S3ServiceRegistry implements ISecurityManagerListener {
/**
* The SingletonHolder is loaded on the first execution of
* SingletonHolder.getInstance() or the first access to
* SingletonHolder.instance
*/
private static class SingletonHolder {
/** The store of the {@link S3ServiceRegistry} instance. */
private final static S3ServiceRegistry instance = new S3ServiceRegistry();
}
/**
* Get the instance of the {@link S3ServiceRegistry}.
*
* @return the instantiated singleton
*/
public static S3ServiceRegistry getRegistry() {
return SingletonHolder.instance;
}
/** The mapping table for the aws access id to service. */
private Hashtable<String, S3Service> services;
/**
* Private constructor to refuse public instantiation.
*/
private S3ServiceRegistry() {
this.services = new Hashtable<String, S3Service>();
AuthenticationTokenManager.getManager().addListener( this );
}
/**
* Clears the list of services.
*/
public void clear() {
this.services.clear();
}
/**
* Get the service for accessing the account represented by the specified
* access key ID. If the service is not yet in the cache it is created and
* cached afterwards.
*
* @param awsAccessId the access id to bind and {@link S3Service} to
* @return The service to make operations on the account with the specified
* access key ID or <code>null</code> if no service could be created
* @throws ProblemException If the service was not yet in the cache and its
* creation failed
*/
public S3Service getService( final String awsAccessId )
throws ProblemException
{
// get the auth token
AWSAuthTokenDescription awsAuthTokenDesc = new AWSAuthTokenDescription( awsAccessId );
AuthTokenRequest request = new AuthTokenRequest( awsAuthTokenDesc,
Messages.getString( "S3ServiceRegistry.auth_requester" ), //$NON-NLS-1$
Messages.getString( "S3ServiceRegistry.auth_request" ) ); //$NON-NLS-1$
AWSAuthToken awsAuthToken = ( AWSAuthToken )AbstractAuthTokenProvider.staticRequestToken( request );
if( awsAuthToken != null ) {
// try to fetch the service
S3Service existingService = this.services.get( awsAuthToken );
if( existingService == null ) {
// create a new service
awsAuthTokenDesc = ( AWSAuthTokenDescription )awsAuthToken.getDescription();
AWSCredentials awsCredentials = new AWSCredentials( awsAuthTokenDesc.getAwsAccessId(),
awsAuthTokenDesc.getAwsSecretId() );
RestS3Service service = null;
try {
service = new RestS3Service( awsCredentials,
IS3Constants.APP_TAG,
null );
} catch( S3ServiceException s3sExc ) {
throw new ProblemException( IS3Problems.REST_SERVICE_CREATION_FAILED,
Activator.PLUGIN_ID );
}
// put new service into the map
AWSAuthTokenDescription activeAuthDesc = ( AWSAuthTokenDescription )awsAuthToken.getDescription();
this.services.put( activeAuthDesc.getAwsAccessId(), service );
return service;
}
return existingService;
}
return null;
}
public void contentChanged( final ISecurityManager manager ) {
if( manager instanceof AuthenticationTokenManager ) {
AuthenticationTokenManager authTokenManager = ( AuthenticationTokenManager )manager;
List<IAuthenticationToken> tokens = authTokenManager.getTokens();
Set<Entry<String, S3Service>> entrySet = this.services.entrySet();
List<String> elementsToRemove = new ArrayList<String>( this.services.size() );
boolean found;
// remove authtoken/s3service mappings if not existing in the authtoken
// manager list
for( Entry<String, S3Service> entry : entrySet ) {
found = false;
for( IAuthenticationToken authToken : tokens ) {
if ( authToken instanceof AWSAuthTokenDescription ) {
AWSAuthTokenDescription awsAuthTokenDesc = ( AWSAuthTokenDescription )authToken.getDescription();
if( entry.getKey() == awsAuthTokenDesc.getAwsAccessId() ) {
found = true;
}
}
}
if( !found ) {
elementsToRemove.add( entry.getKey() );
}
}
for( String awsAccessId : elementsToRemove ) {
this.services.remove( awsAccessId );
}
}
}
}