/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
/**
* @author Neeraj Joshi <jneeraj@us.ibm.com>
*
*/
package org.apache.imperius.cimspl.client;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.imperius.spl.core.Argument;
import org.apache.imperius.spl.core.DataCollector;
import org.apache.imperius.spl.core.TypeConstants;
import org.apache.imperius.spl.parser.compiler.symboltable.MethodSymbol;
import org.apache.imperius.spl.parser.compiler.symboltable.PropertySymbol;
import org.apache.imperius.spl.parser.compiler.symboltable.SPLSymbolTable;
import org.apache.imperius.spl.parser.compiler.symboltable.Symbol;
import org.apache.imperius.spl.parser.exceptions.ClassDoesNotExistException;
import org.apache.imperius.spl.parser.exceptions.InstanceDoesNotExistException;
import org.apache.imperius.spl.parser.exceptions.InvalidCIMParameterException;
import org.apache.imperius.spl.parser.exceptions.SPLException;
import org.apache.imperius.spl.parser.statements.impl.ArgumentImpl;
import org.apache.imperius.util.SPLLogger;
import org.sblim.wbem.cim.CIMClass;
import org.sblim.wbem.cim.CIMException;
import org.sblim.wbem.cim.CIMInstance;
import org.sblim.wbem.cim.CIMMethod;
import org.sblim.wbem.cim.CIMObjectPath;
import org.sblim.wbem.cim.CIMParameter;
import org.sblim.wbem.cim.CIMProperty;
import org.sblim.wbem.client.CIMClient;
public class CIMClientSideDataCollectorImpl implements DataCollector
{
private static CIMClient _handle;
private static Logger logger = SPLLogger.getSPLLogger().getLogger();
private static String sourceClass = "CIM_SPLPolicyRuleProvider";
public CIMClientSideDataCollectorImpl(CIMClient ch)
{
_handle=ch;
}
private void _populateClassProperties(CIMClass cimClass, String classPath, Map symbols) throws SPLException
{
Vector properties=_getPropertiesOfClass(cimClass ,classPath );
for(int i=0;i<properties.size();i++)
{
CIMProperty cimproperty=(CIMProperty) properties.get(i);
String qualifiedPropertyName= cimproperty.getName();
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" PropertyName "+cimproperty.getName().toLowerCase());
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" qualifiedPropertyName "+qualifiedPropertyName);
// //add the property to the HashMap as(class.propertyName, PropertySymbol)
if( ! symbols.containsKey(qualifiedPropertyName))
{
int type=CIMSPLTypeConstants.convertCIMTypeToInternalType(cimproperty.getType().getType());
String referenceTypeName="";
if(type == TypeConstants.referenceType)
{
String path=(String)cimproperty.getValue().getValue();
//the property is a CIMObjectPath
referenceTypeName=CIMSPLTypeConstants.getReferenceTypeName(path);
}
boolean isArray = CIMSPLTypeConstants.getIsArray(cimproperty.getType().getType());
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" symboltable does not currently contain the given property, so creating property symbol");
Symbol symbol = new PropertySymbol(qualifiedPropertyName,type,referenceTypeName,isArray,_isKey(cimproperty),true);
//add property to properties list
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" adding property to Map in datacollector : "+qualifiedPropertyName);
symbols.put(qualifiedPropertyName, symbol);
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" symboltable already contains the given symbol "+cimproperty.getName().toLowerCase());
logger.severe(qualifiedPropertyName+" symbol Already exists in SymbolTable");
throw new SPLException("symbol Already exists in SymbolTable");
}
}
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" done adding all the properties");
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" get all methods of the class and iterate over them");
}
private void _populateClassMethods(CIMClass cimClass, Map symbols) throws SPLException
{
Vector methods = cimClass.getAllMethods();
//get all methods of the class and iterate over them
for(int i=0;i<methods.size();i++)
{
CIMMethod cimMethod= (CIMMethod)methods.get(i);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" method : "+cimMethod.getName()+
" Parameter count "+cimMethod.getParameters()+" is of type "+cimMethod.getType());
// //ArrayList argTypeList=new ArrayList ();
List methodArgs=new ArrayList();
SPLSymbolTable methodArgsSymbolTable=new SPLSymbolTable();
Vector parameters = cimMethod.getParameters();
for(int j=0; j<parameters.size(); j++)
{
CIMParameter cimparameter = (CIMParameter)parameters.get(j);
String parameterName=cimparameter.getName();
//boolean isArr=cimparameter.isArray();
int type=CIMSPLTypeConstants.convertCIMTypeToInternalType(cimparameter.getType().getType());
boolean isArray = CIMSPLTypeConstants.getIsArray(cimparameter.getType().getType());
String referenceTypeName="";
if(type == TypeConstants.referenceType)
{
referenceTypeName = CIMSPLTypeConstants.getReferenceTypeName(cimparameter.getName());
}
Argument arg=new ArgumentImpl(type, parameterName, isArray, referenceTypeName);
methodArgsSymbolTable.insertVariableSymbol(parameterName, type, referenceTypeName, isArray, false, false);
//System.out.println(" inserted variable symbol into methodArgsSymbolTable "+parameterName);
methodArgs.add(arg);
}
String methodName=cimMethod.getName();
if( ! symbols.containsKey(methodName))
{
int localReturnType=CIMSPLTypeConstants.convertCIMTypeToInternalType(cimMethod.getType().getType());
Symbol methodSymbol = new MethodSymbol(methodName,localReturnType,
CIMSPLTypeConstants.getIsArray(localReturnType),cimClass.getName(),methodArgs,methodArgsSymbolTable);
//add property to properties list
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" adding method to symbol table" + methodName);
symbols.put(methodName, methodSymbol);
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" SymbolTable already contains the given method "+methodName);
logger.severe(Thread.currentThread().getName()+" "+"SymbolTable already contains the given method "+methodName);
throw new CIMException("SymbolTable already contains the given method "+methodName);
}
}
}
private void _populateClassMembers(String className,String classPath, Map symbolMap) throws SPLException
{
if(className!=null && classPath!=null)
{
CIMObjectPath cop=new CIMObjectPath(className,classPath);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" cop "+cop);
Map symbols=symbolMap;
//get class
try
{
//System.out.println("_handle.getClass");
CIMClass cimClass=_handle.getClass(cop, true, true, true, null);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" got class "+cimClass.getName());
if(cimClass!=null)
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" get all the properties of the class and iterate over them");
//System.out.println("get all the properties of the class and iterate over them");
//get all the properties of the class and iterate over them
_populateClassProperties(cimClass, classPath, symbols);
_populateClassMethods(cimClass,symbols);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" done adding methods to the symboltable");
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "getSymbolsForClass");
//return symbols;
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" handle : the cimclass is null");
logger.severe(Thread.currentThread().getName()+" "+"This CIM class does not exist");
throw new ClassDoesNotExistException("This CIM class does not exist");
}
}
catch (CIMException e){
logger.severe(Thread.currentThread().getName()+" "+"Failed to get class "+e.getMessage());
throw new SPLException("Failed to get class");
}
}
else
{
logger.severe(Thread.currentThread().getName()+" "+"This CIM class is not handled by the Policy Provider");
throw new InvalidCIMParameterException("This CIM class is not handled by the Policy Provider");
}
}
public Map getSymbolsForClass(String className, String qualifier)
throws SPLException
{
String formattedClass = null;
if(className.startsWith("\"")) // string of form ""lkasdlk""
{
formattedClass = className.substring(1, className.length() -1 );
}
else
{
formattedClass = className;
}
//System.out.println("formatted class" + formattedClass);
Map symbolMap = new Hashtable();
_populateClassMembers(formattedClass,qualifier,symbolMap);
return symbolMap;
}
public Map getSymbolsForInstance(String className, String namespc, Object cop)
throws SPLException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "getInstanceMap");
if(cop instanceof CIMObjectPath)
{
// CIMObjectPath cimObjectPath= new CIMObjectPath(className,namespc);
// CIMObjectPath cop1=(CIMObjectPath)cop;
// cimObjectPath.setKeys(cop1.getKeys());
try{
CIMInstance ci=_handle.getInstance((CIMObjectPath)cop, true, true, true, null);
Map instanceProperties=new HashMap();
//get all properties of the current instance
Vector properties=ci.getAllProperties();
for(int i=0;i<properties.size();i++)
{
//add property to HashMap as (class.name,value) pair
CIMProperty cimproperty=(CIMProperty) properties.get(i);
String qualifiedPropertyName= cimproperty.getName();
instanceProperties.put(qualifiedPropertyName, cimproperty.getValue().getValue());
}
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "getInstanceMap");
return instanceProperties;
}
catch(CIMException e)
{
logger.severe(e.getMessage());
throw new SPLException(e.getMessage());
}
}
else
{
throw new SPLException("Reference is not of Type CIMObjectPath");
}
}
public List getAssociatedInstanceNames(
Object srcInstanceName,
String nameSpace,
String resultClass,
String assocClass,
String role,
String resultRole) throws SPLException
{
return null;
}
// public List getAssociatedInstances(Object refExpressionResult, String nameSpace, String targetClassName, String associationName, String sourceRole, String targetRole) {
// // TODO Auto-generated method stub
// return null;
// }
private static Vector _getPropertiesOfClass(CIMClass cimClass ,String classPath ) throws CIMException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "getPropertiesOfClass");
CIMClass cimclass=cimClass;
Vector propertyNames=new Vector();
Vector properties=cimclass.getAllProperties();
Iterator it=properties.iterator();
String superClass=cimclass.getSuperClass();
while(it.hasNext())
{
CIMProperty cimProp=(CIMProperty)it.next();
//System.out.println("cimProp "+cimProp.toString());
String propName=cimProp.getName();
//System.out.println("propName "+propName);
propertyNames.add(propName);
}
superClass=cimclass.getSuperClass();
while((superClass!= null)&&(superClass!= "")&&(superClass.length()!=0))
{
CIMObjectPath cop=new CIMObjectPath(superClass,classPath);
cimclass=_handle.getClass(cop, true, true, true, null);
Vector propertiesSuper=cimclass.getAllProperties();
Iterator proppertiesSuperIt=propertiesSuper.iterator();
while(proppertiesSuperIt.hasNext())
{
CIMProperty cimProp=(CIMProperty)proppertiesSuperIt.next();
if (!propertyNames.contains(cimProp.getName()))
{
properties.add(cimProp);
String propName=cimProp.getName();
propertyNames.add(propName);
if(logger.isLoggable(Level.FINE))
logger.fine(cimProp.getName()+"new superclass property found "+cimProp.getName());
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(cimProp.getName()+"already exists ,Super class variable ignored");
}
}
superClass=cimclass.getSuperClass();
}
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "getPropertiesOfClass");
return properties;
}
private boolean _isKey(CIMProperty cimProperty)
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "_isKey");
boolean res = cimProperty.isKey();
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "_isKey" + res);
return res;
}
public List enumerateInstanceNames(String className, String namespace)
throws SPLException
{
String formattedClass = null;
if(className.startsWith("\"")) // string of form ""lkasdlk""
{
formattedClass = className.substring(1, className.length() -1 );
}
else
{
formattedClass = className;
}
//System.out.println("formatted class" + formattedClass);
CIMObjectPath classCop=new CIMObjectPath(formattedClass,namespace);
List instanceList=new ArrayList();
try{
Enumeration instanceEnumeration=_handle.enumerateInstanceNames(classCop);
while(instanceEnumeration.hasMoreElements())
{
instanceList.add(instanceEnumeration.nextElement());
}
return instanceList;
}
catch (CIMException e){
throw new SPLException(e.getMessage());
}
}
public boolean associationExists(String className ,String classPath, String resultClass,
String assocClass, String role, String resultRole) throws SPLException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "associationExists");
CIMObjectPath cop=new CIMObjectPath(assocClass,classPath);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" associationExists::cop ::"+cop);
try
{
CIMClass associationClass=_handle.getClass(cop, true, true, true, null);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" got class "+associationClass.getName());
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" check to see if the class is an association");
//check to see if the class is an association
boolean isAssoc=associationClass.isAssociation();
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" CIMClass, isAssociation()= "+
isAssoc+" "+associationClass.getAllProperties().toString());
if(isAssoc)
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" class is an association");
CIMProperty srcProperty=associationClass.getProperty(role);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" check to see if the role played by src class is correct");
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" src RefClassName(),className::"+
srcProperty.getOriginClass()+" "+className);
//check to see if the role played by src class is correct
if(_classNameMatchesString(srcProperty.getType().getRefClassName().trim(), classPath, className))
{
CIMProperty resultProperty=associationClass.getProperty(resultRole);
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" check to see if role played by result class is corrrect");
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" result RefClassName(),className::"+
resultProperty.getType().getRefClassName()+" "+resultClass);
//check to see if role played by result class is corrrect
if(_classNameMatchesString(resultProperty.getType().getRefClassName().trim(), classPath, resultClass))
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" associationExists returning true");
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "associationExists");
return true;
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" associationExists returning false " +
"because of resultClass "+resultClass+ " "+resultProperty.getType().getRefClassName());
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "associationExists");
return false;
}
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" associationExists returning false because of className "+
className+ " != "+srcProperty.getType().getRefClassName());
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "associationExists");
return false;
}
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" associationExists returning false because CIMClass.isAssociation()= "+isAssoc);
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "associationExists");
return false;
}
}
catch (CIMException e){
logger.severe(Thread.currentThread().getName()+" "+"Failed to get class");
throw new SPLException("Failed to get class");
}
}
private static boolean _classNameMatchesString(String str,String namespace,String className ) throws CIMException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "classNameMatchesString");
//CIMClass cimclass=cimClass;
//Vector propertyNames=new Vector();
System.out.println("associationExists ->classnm.equalsIgnoreCase(str) "+className+" "+namespace+" "+str);
CIMObjectPath copOriginal=new CIMObjectPath(className,namespace);
CIMClass cimclass=_handle.getClass(copOriginal, true, true, true, null);
String classnm=cimclass.getName();
String superClass=cimclass.getSuperClass();
if(classnm.equalsIgnoreCase(str))
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" classNameMatchesString "+classnm+ " "+str);
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "classNameMatchesString");
return true;
}
else if(superClass!= null)
{
while((superClass!= "")&&(superClass.length()!=0))
{
////System.out.println("superclass "+superClass);
if(superClass.equalsIgnoreCase(str))
{
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" classNameMatchesString "+superClass+ " "+str);
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "classNameMatchesString");
return true;
}
else
{
if(logger.isLoggable(Level.FINE))
logger.fine(superClass+" did not Match "+str+" ,trying superclass");
CIMObjectPath cop=new CIMObjectPath(superClass,namespace);
cimclass=_handle.getClass(cop, true, true, true, null);
superClass=cimclass.getSuperClass();
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" new superclass= "+superClass);
}
}
}
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" string did not match classname or superclass names "+str);
logger.exiting(sourceClass,Thread.currentThread().getName()+" "+ "classNameMatchesString");
return false;
}
public List getAssociatedInstanceReferences(Object srcReference, String classPath,
String resultInstancesClassFilter, String assocClass,
String role, String resultRole) throws SPLException
{
logger.entering(sourceClass,Thread.currentThread().getName()+" "+ "getAssociatedInstanceReferences");
CIMObjectPath srcRef=(CIMObjectPath)srcReference;
String className=srcRef.getObjectName();
if(logger.isLoggable(Level.FINE))
{
logger.fine(className+" "+classPath+" "+resultInstancesClassFilter+" "
+ assocClass+" "+role+" "+ resultRole+" "+ srcReference.toString());
}
if(className!=null && classPath!=null)
{
try
{
List instanceREFList = new ArrayList();
//check to see if the association exists
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" check to see if the association exists");
if(associationExists(className ,classPath,resultInstancesClassFilter,assocClass,role,resultRole))
{
//create cop of anchor object
CIMObjectPath cop=new CIMObjectPath(className,classPath);
cop.setKeys(srcRef.getKeys());
//add keys of the source instance to the cop
if(logger.isLoggable(Level.FINE))
logger.fine(Thread.currentThread().getName()+" Anchor Object cop "+cop);
Enumeration targetInstances = _handle.associatorNames(srcRef, assocClass, resultInstancesClassFilter, role, resultRole);
while(targetInstances.hasMoreElements())
{
instanceREFList.add(targetInstances.nextElement());
}
return instanceREFList;
}
else
{
logger.severe(Thread.currentThread().getName()+" "+"The instance does not exist");
throw new InstanceDoesNotExistException("The instance does not exist");
}
}
catch(CIMException e)
{
e.printStackTrace();
logger.severe(Thread.currentThread().getName()+" "+e.getMessage());
throw new SPLException(e.getMessage());
}
}
else
{
logger.severe(Thread.currentThread().getName()+" "+"This CIM class is not handled by the Policy Provider");
throw new InvalidCIMParameterException("This CIM class is not handled by the Policy Provider");
}
}
public String getReferenceTypeName(String reference)
{
//extract class name and return
String referenceType = CIMSPLTypeConstants.getReferenceTypeName(reference);
return referenceType;
}
public boolean isInstance(String className, Object instance)
throws SPLException
{
CIMObjectPath cop = (CIMObjectPath)instance;
String instClassName = cop.getObjectName();
if(className.equals(instClassName))
return true;
return false;
}
}