/*
*
* 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.site.classes;
import edu.isi.pegasus.planner.catalog.site.classes.FileServerType.OPERATION;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
import edu.isi.pegasus.planner.common.PegRandom;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* An abstract base class that creates a directory type. It associates multiple
* file servers and an internal mount point.
*
* @author Karan Vahi
*/
public abstract class DirectoryLayout extends AbstractSiteData{
/**
* The list of file servers that can be used to write to access this directory
* indexed by operation type.
*/
//protected List<FileServer> mFileServers;
protected Map<FileServer.OPERATION, List<FileServer>> mFileServers;
/**
* The internal mount point for the directory.
*/
protected InternalMountPoint mInternalMount;
/**
* The default constructor.
*/
public DirectoryLayout(){
initialize( );
}
/**
* The copy constructor
*/
public DirectoryLayout( DirectoryLayout directory ){
this.initialize( directory.mFileServers, directory.getInternalMountPoint() );
}
/**
* The overloaded constructor
*
* @param fs map of file servers indexed by FileServer operation
* @param imt the internal mount point.
*/
public DirectoryLayout( Map<FileServer.OPERATION, List<FileServer>> fs, InternalMountPoint imt ){
initialize( fs, imt );
}
/**
* Initializes the object
*
*/
private void initialize( ){
this.mFileServers = new HashMap<FileServer.OPERATION, List<FileServer>> ();
this.resetFileServers();
this.mInternalMount = new InternalMountPoint();
}
/**
* Initializes the object
*
* @param fs list of file servers indexed by operation type
* @param imt the internal mount point.
*/
private void initialize( Map<FileServer.OPERATION, List<FileServer>> fs, InternalMountPoint imt ){
this.mFileServers = fs;
this.mInternalMount = imt ;
}
/**
* Adds a FileServer that can access this directory.
*
* @param server the file server.
*/
public void addFileServer( FileServer server ){
List<FileServer> l = mFileServers.get( server.getSupportedOperation());
l.add(server);
}
/**
* Sets the list of FileServers that can access this directory.
*
* @param servers the list of servers
*/
public void setFileServers( List<FileServer> servers ){
this.resetFileServers();
for( FileServer server: servers ){
this.addFileServer(server);
}
}
/**
* Selects a random file server and returns it matching an operation type.
* If not found matching the operation type it defaults back to the all operation
* server.
*
* @param operation the operation for which the file server is required
*
* @return FileServer else null
*/
public FileServer selectFileServer( FileServer.OPERATION operation ){
List<FileServer> servers = getFileServers(operation);
if (servers == null || servers.isEmpty() ) {
servers = getFileServers( FileServer.OPERATION.all );
}
return ( servers == null || servers.isEmpty() )?
null:
servers.get( PegRandom.getInteger( servers.size() - 1) );
/*
return ( this.mFileServers == null || this.mFileServers.size() == 0 )?
null :
this.mFileServers.get( PegRandom.getInteger( this.mFileServers.size() - 1) );
*/
}
/**
* Selects all file servers and returns it matching an operation type.
*
* @param operation the operation for which the file server is required
*
* @return List of FileServer else null
*/
public List<FileServer> getFileServers( FileServer.OPERATION operation ){
List<FileServer> servers = this.mFileServers.get(operation);
return servers;
}
/**
* A convenience method that retrieves whether the directory has a
* file server for get operations ( file server with type get and all )
*
* @return boolean
*/
public boolean hasFileServerForGETOperations(){
return this.hasFileServerForOperations( OPERATION.get );
}
/**
* A convenience method that retrieves whether the directory has a
* file server for put operations ( file server with type put and all )
*
* @return boolean
*/
public boolean hasFileServerForPUTOperations(){
return this.hasFileServerForOperations( OPERATION.put );
}
/**
* A convenience method that retrieves whether the directory has a
* file server for a particular operation. Servers with operation type as ALL
* are also considered.
*
*
* @param operation the operation for which we need the file servers
*
* @return boolean
*/
public boolean hasFileServerForOperations( FileServer.OPERATION operation ){
return !(this.mFileServers.get( FileServer.OPERATION.all ).isEmpty()
&& this.mFileServers.get( operation ).isEmpty());
}
/**
* Returns at iterator to the file servers.
*
* @return Iterator<FileServer>
*/
public Iterator<FileServer> getFileServersIterator( FileServer.OPERATION operation ){
return mFileServers.get( operation).iterator();
}
/**
* Sets the internal mount point for the directory.
*
* @param mountPoint the internal mount point.
*/
public void setInternalMountPoint( InternalMountPoint mountPoint ){
mInternalMount = mountPoint;
}
/**
* Returns the internal mount point for the directory.
*
* @return the internal mount point.
*/
public InternalMountPoint getInternalMountPoint(){
return this.mInternalMount;
}
/***
* A convenience method that returns true if all the attributes values are
* uninitialized or empty strings. Useful for serializing the object as
* XML.
*
* @return boolean
*/
public boolean isEmpty(){
boolean result = true;
//we need to check if each file servers for each supported
//operation are empty or not.
for( FileServer.OPERATION operation : FileServer.OPERATION.values() ){
result = result && this.mFileServers.get( operation ).isEmpty();
if( !result ){
//break out of the computation.
break;
}
}
return result && this.getInternalMountPoint().isEmpty();
}
/**
* Resets the internal collection of file servers
*/
public void resetFileServers(){
for( OPERATION op : FileServer.OPERATION.values() ){
this.mFileServers.put( op, new LinkedList<FileServer>() );
}
}
/**
* Returns the clone of the object.
*
* @return the clone
*/
public Object clone(){
DirectoryLayout obj;
try{
obj = ( DirectoryLayout ) super.clone();
}
catch( CloneNotSupportedException e ){
//somewhere in the hierarch chain clone is not implemented
throw new RuntimeException("Clone not implemented in the base class of " + this.getClass().getName(),
e );
}
obj.initialize( );
obj.setInternalMountPoint( (InternalMountPoint)mInternalMount.clone() );
for( OPERATION op : FileServer.OPERATION.values() ){
List<FileServer> servers = this.mFileServers.get( op );
for( FileServer server : servers ){
obj.addFileServer( (FileServer)server.clone() );
}
}
return obj;
}
}