/**
* Copyright 2007-2008 University Of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.isi.pegasus.planner.catalog.transformation.classes;
import edu.isi.pegasus.common.util.Separator;
import edu.isi.pegasus.planner.catalog.transformation.TransformationCatalogEntry;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
*
* A container data class that is used to store transformations. The transformation
* are stored internally indexed by transformation name.
*
* @author Karan Vahi
* @version $Revision$
*/
public class TransformationStore {
/**
* The internal store map. The Map is indexed by transformation names.
* The corresponding value is a Map that contains entries for all sites for
* a particular transformation . This map is indexed by site name and
* corresponding values are Lists of TransformationCatalogEntry objects.
*
*/
private Map<String, Map<String,List<TransformationCatalogEntry>>> mTCStore;
/**
* The default constructor.
*/
public TransformationStore(){
initialize();
}
/**
* Intializes the store.
*/
private void initialize(){
mTCStore = new TreeMap<String, Map<String,List<TransformationCatalogEntry>>>();
}
/**
* Clears all the entries in the store.
*/
public void clear(){
//more efficient to create a new object rather than relying on
//the underlying map clear method
initialize();
}
/**
* Adds an entry into the store. If the entry already exists i.e entry
* for a site and corresponding PFN exists it's overriden.
*
* @param entry the transformation catalog object.
*/
public void addEntry( TransformationCatalogEntry entry ){
String completeName = entry.getLogicalTransformation();
if( this.containsTransformation( completeName )){
//retrieve the associated map
Map<String,List<TransformationCatalogEntry>> m = mTCStore.get( completeName );
//check if the transformation is defined for a particular site
if( m.containsKey( entry.getResourceId() ) ){
//add an existing entry
List<TransformationCatalogEntry> l = m.get( entry.getResourceId() );
boolean existing = false;
for( TransformationCatalogEntry e : l ){
//PM-888 instead of only matching on PFN we now match on the
//whole transformation catalog entry. since, we can have
//two entries with same PFN but ( different osrelease i.e osrlease
//specified for one entry and not for the other)
if( e.equals( entry ) ){
//lets overwrite the entry and break out
l.remove( e );
l.add( entry );
existing = true;
break;
}
}
if ( !existing ){
//an entry with the same pfn does not exist for the site
l.add( entry );
}
}
else{
//no entries for the transformation at the site entry.getResourceId()
List<TransformationCatalogEntry> l = new LinkedList();
l.add( entry );
m.put( entry.getResourceId(), l );
}
}
else{
Map<String, List<TransformationCatalogEntry>> m = new HashMap();
List l = new LinkedList();
l.add( entry );
m.put( entry.getResourceId(), l );
mTCStore.put(completeName, m );
}
}
/**
* Returns List of TransformationCatalogEntry objects for a transformation
* on a particular site and a type. If the site parameter passed is null, then all
* entries are returned corresponding to a tranformation. If type is null,
* then all entries associated with a site are returned.
*
* @param completeName the complete name of the transformation
* @param site the site on which to search for entries. null means all
* @param type the type to match on . null means all types.
*
* @return List if entries are found , else empty list.
*/
public List<TransformationCatalogEntry> getEntries( String completeName, String site, TCType type ){
//retrieve all entries for a site
List<TransformationCatalogEntry> result = null;
//check whether we need to filter on type ?
if( type == null ){
result = this.getEntries( completeName, site );
}
else{
result = new LinkedList();
for( TransformationCatalogEntry entry : this.getEntries(completeName, site) ){
if( entry.getType().equals( type ) ){
result.add( entry );
}
}
}
return result;
}
/**
* Returns List of TransformationCatalogEntry objects for a transformation
* on a particular site. If the site parameter passed is null, then all
* entries are returned corresponding to a tranformation.
*
* @param completeName the complete name of the transformation
* @param site the site on which to search for entries. null means all sites
*
* @return List if entries are found , else empty list.
*/
public List<TransformationCatalogEntry> getEntries( String completeName, String site){
List<TransformationCatalogEntry> result = new LinkedList();
if( this.containsTransformation( completeName )){
Map<String,List<TransformationCatalogEntry>> m = mTCStore.get( completeName );
if( site == null ){
//return all entries
for( Map.Entry<String, List<TransformationCatalogEntry>> entry :m.entrySet() ){
result.addAll( entry.getValue() );
}
}
else if ( m.containsKey( site ) ){
//retrieve all the entries for the site.
result.addAll( m.get( site ) );
}
}
return result;
}
/**
* Returns all the entries in the Transformation Store
*
* @return all entries.
*/
public List<TransformationCatalogEntry> getAllEntries( ){
return this.getEntries( (String)null, (TCType)null );
}
/**
* Returns a list of TransformationCatalogEntry objects matching on a site and
* transformation type.
*
*
* @param site the site on which to search for entries. null means all
* @param type the type to match on . null means all types.
*
* @return List if transformations exist
*/
public List<TransformationCatalogEntry> getEntries( String site, TCType type ){
List<TransformationCatalogEntry> result = new LinkedList();
//retrieve list of all transformation names
for( String name: mTCStore.keySet() ){
result.addAll( this.getEntries( name, site, type ));
}
return result;
}
/**
* Returns a list of transformation names matching on a site and
* transformation type.
*
*
* @param site the site on which to search for entries. null means all
* @param type the type to match on . null means all types.
*
* @return List if transformations exist
*/
public List<String> getTransformations( String site, TCType type ){
List<String> result = new LinkedList();
if( site == null && type == null ){
//retrieve list of all transformation names
for( String name: mTCStore.keySet() ){
result.add(name);
}
return result;
}
else if ( type == null ){
//no matching on type required only on site
for( String name: mTCStore.keySet() ){
Map<String,List<TransformationCatalogEntry>> m = mTCStore.get( name );
for( String s: m.keySet() ){
if( s.equals( site ) ){
result.add( name );
break;
}
}
}
}
else{
//(site == null || site is not null ) and match on type
for( String name: mTCStore.keySet() ){
Map<String,List<TransformationCatalogEntry>> m = mTCStore.get( name );
for( String s: m.keySet() ){
boolean matchFound = false;
//either site name matches or we searching for all sites
if( site == null || site.equals( s )){
//traverse through all entries and match on type
List<TransformationCatalogEntry> l = m.get( s );
for( TransformationCatalogEntry entry : l ){
if( entry.getType().equals( type )){
result.add( name );
matchFound = true;
break;
}
}
}
if( matchFound ){
break;
}
}//end of iterating entries for sites
}//end of iteration over all transformation names
}
return result;
}
/**
* Returns a boolean indicating whether the store contains an entry
* corresponding to a particular transformation or not.
*
* @param namespace the namespace associated with the transformation
* @param name the logical name
* @param version the version of the transformation
*
* @return boolean
*/
public boolean containsTransformation( String namespace, String name, String version ){
return this.mTCStore.containsKey( Separator.combine(namespace, name, version) );
}
/**
* Returns a boolean indicating whether the store contains an entry
* corresponding to a particular transformation or not.
*
* @param completeName the complete name of the transformation as constructed from
* namespace, name and version
*
* @return boolean
*/
public boolean containsTransformation( String completeName ){
return this.mTCStore.containsKey( completeName );
}
}