/**
* Copyright 2007-2015 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.namespace;
import edu.isi.pegasus.planner.catalog.classes.Profiles;
import edu.isi.pegasus.planner.classes.Profile;
import edu.isi.pegasus.planner.common.PegasusProperties;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
/**
*
* @author Karan Vahi
*
* @version $Revision$
*/
public class Metadata extends Namespace {
/**
* The name of the namespace that this class implements.
*/
public static final String NAMESPACE_NAME = Profile.METADATA;
/**
* The name of the implementing namespace. It should be one of the valid
* namespaces always.
*
* @see Namespace#isNamespaceValid(String)
*/
protected String mNamespace;
/**
* The default constructor.
* Note that the map is not allocated memory at this stage. It is done so
* in the overloaded construct function.
*/
public Metadata() {
mProfileMap = null;
mNamespace = NAMESPACE_NAME;
}
/**
* The overloaded constructor.
*
* @param mp the map containing the profiles to be prepopulated with.
*/
public Metadata(Map mp) {
mProfileMap = new HashMap(mp);
mNamespace = NAMESPACE_NAME;
}
/**
* Returns the name of the namespace associated with the profile implementations.
*
* @return the namespace name.
* @see #NAMESPACE_NAME
*/
public String namespaceName(){
return mNamespace;
}
/**
* Provides an iterator to traverse the profiles by their keys.
*
* @return an iterator over the keys to walk the profile list.
*/
public Iterator getProfileKeyIterator() {
return ( this.mProfileMap == null ) ? new EmptyIterator() : this.mProfileMap.keySet().iterator();
}
/**
* Constructs a new element of the format (key=value). It first checks if
* the map has been initialised or not. If not then allocates memory first.
*
* @param key is the left-hand-side.
* @param value is the right hand side.
*/
public void construct(String key, String value) {
if(mProfileMap == null)
mProfileMap = new HashMap();
mProfileMap.put(key, value);
}
/**
* Returns true if the namespace contains a mapping for the specified key.
* More formally, returns true if and only if this map contains at a mapping
* for a key k such that (key==null ? k==null : key.equals(k)).
* (There can be at most one such mapping.)
* It also returns false if the map does not exist.
*
* @param key The key that you want to search for
* in the namespace.
*
* @return boolean
*/
public boolean containsKey(Object key){
return (mProfileMap == null)? false : mProfileMap.containsKey(key);
}
/**
* This checks whether the key passed by the user is valid in the current
* namespace or not. At present, for this namespace only a limited number of
* keys have been assigned semantics.
*
* @param key (left hand side)
* @param value (right hand side)
*
* @return Namespace.VALID_KEY
* @return Namespace.NOT_PERMITTED_KEY
*
*/
public int checkKey(String key, String value) {
// sanity checks first
int res = 0;
if (key == null || key.length() < 2 ||
value == null || value.length() < 2) {
res = MALFORMED_KEY ;
}
//all keys are permitted currenlyt
switch (key.charAt(0)) {
default:
res = VALID_KEY;
}
return res;
}
/**
* It puts in the namespace specific information specified in the properties
* file into the namespace. The name of the pool is also passed, as many of
* the properties specified in the properties file are on a per pool basis.
* An empty implementation for the timebeing.
*
* @param properties the <code>PegasusProperties</code> object containing
* all the properties that the user specified at various
* places (like .chimerarc, properties file, command line).
* @param pool the pool name where the job is scheduled to run.
*/
public void checkKeyInNS(PegasusProperties properties, String pool){
//retrieve the relevant profiles from properties
//and merge them into the existing.
this.assimilate( properties, Profiles.NAMESPACES.metadata );
}
/**
* Merge the profiles in the namespace in a controlled manner.
* In case of intersection, the new profile value overrides, the existing
* profile value.
*
* @param profiles the <code>Namespace</code> object containing the profiles.
*/
public void merge( Namespace profiles ){
//check if we are merging profiles of same type
if (!(profiles instanceof Metadata )){
//throw an error
throw new IllegalArgumentException( "Profiles mismatch while merging" );
}
String key;
for ( Iterator it = profiles.getProfileKeyIterator(); it.hasNext(); ){
//construct directly. bypassing the checks!
key = (String)it.next();
this.construct( key, (String)profiles.get( key ) );
}
}
/**
* Converts the contents of the map into the string that can be put in the
* Condor file for printing.
*
* @return an empty string
*/
public String toCondor() {
return "";
}
/**
* Returns a copy of the current namespace object.
*
* @return the Cloned object
*/
public Object clone() {
return (mProfileMap == null)?new Metadata():new Metadata(this.mProfileMap);
}
}