package org.ovirt.engine.core.searchbackend;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.ovirt.engine.core.compat.StringFormat;
import org.ovirt.engine.core.searchbackend.gluster.GlusterVolumeConditionFieldAutoCompleter;
import org.ovirt.engine.core.searchbackend.gluster.GlusterVolumeCrossRefAutoCompleter;
public class SearchObjectAutoCompleter extends SearchObjectsBaseAutoCompleter {
private final Map<String, String[]> joinDictionary = new HashMap<>();
private final Map<String, Boolean> requiresFullTable = new HashMap<>();
public SearchObjectAutoCompleter() {
verbs.add(SearchObjects.VM_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDC_POOL_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDS_PLU_OBJ_NAME);
verbs.add(SearchObjects.TEMPLATE_PLU_OBJ_NAME);
verbs.add(SearchObjects.AUDIT_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDC_USER_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDC_GROUP_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDC_CLUSTER_PLU_OBJ_NAME);
verbs.add(SearchObjects.DISK_PLU_OBJ_NAME);
verbs.add(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME);
verbs.add(SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME);
verbs.add(SearchObjects.GLUSTER_VOLUME_PLU_OBJ_NAME);
verbs.add(SearchObjects.QUOTA_OBJ_NAME);
verbs.add(SearchObjects.NETWORK_PLU_OBJ_NAME);
verbs.add(SearchObjects.PROVIDER_PLU_OBJ_NAME);
verbs.add(SearchObjects.INSTANCE_TYPE_PLU_OBJ_NAME);
verbs.add(SearchObjects.IMAGE_TYPE_PLU_OBJ_NAME);
verbs.add(SearchObjects.SESSION_PLU_OBJ_NAME);
buildCompletions();
verbs.add(SearchObjects.VM_OBJ_NAME);
verbs.add(SearchObjects.VDC_POOL_OBJ_NAME);
verbs.add(SearchObjects.DISK_OBJ_NAME);
verbs.add(SearchObjects.VDS_OBJ_NAME);
verbs.add(SearchObjects.TEMPLATE_OBJ_NAME);
verbs.add(SearchObjects.AUDIT_OBJ_NAME);
verbs.add(SearchObjects.VDC_USER_OBJ_NAME);
verbs.add(SearchObjects.VDC_GROUP_OBJ_NAME);
verbs.add(SearchObjects.VDC_CLUSTER_OBJ_NAME);
verbs.add(SearchObjects.GLUSTER_VOLUME_OBJ_NAME);
verbs.add(SearchObjects.NETWORK_OBJ_NAME);
verbs.add(SearchObjects.PROVIDER_OBJ_NAME);
verbs.add(SearchObjects.INSTANCE_TYPE_OBJ_NAME);
verbs.add(SearchObjects.IMAGE_TYPE_OBJ_NAME);
verbs.add(SearchObjects.SESSION_OBJ_NAME);
requiresFullTable.put(SearchObjects.VDC_USER_ROLE_SEARCH, true);
// vms - vds
addJoin(SearchObjects.VM_OBJ_NAME,
"run_on_vds",
SearchObjects.VDS_OBJ_NAME,
"vds_id");
// vms - vmt
addJoin(SearchObjects.VM_OBJ_NAME,
"vmt_guid",
SearchObjects.TEMPLATE_OBJ_NAME,
"vmt_guid");
// vms - users
addJoin(SearchObjects.VM_OBJ_NAME,
"vm_guid",
SearchObjects.VDC_USER_OBJ_NAME,
"vm_guid");
// vms - audit
addJoin(SearchObjects.VM_OBJ_NAME,
"vm_guid",
SearchObjects.AUDIT_OBJ_NAME,
"vm_id");
// vms - vm network interface
addJoin(SearchObjects.VM_OBJ_NAME,
"vm_guid",
SearchObjects.VM_NETWORK_INTERFACE_OBJ_NAME,
"vm_guid");
// vms - storage domain
addJoin(SearchObjects.VM_OBJ_NAME,
"storage_id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// templates - storage domain
addJoin(SearchObjects.TEMPLATE_OBJ_NAME,
"storage_id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// image-type - storage domain
addJoin(SearchObjects.IMAGE_TYPE_OBJ_NAME,
"storage_id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// templates - vm template network interface
addJoin(SearchObjects.TEMPLATE_OBJ_NAME,
"vmt_guid",
SearchObjects.VM_NETWORK_INTERFACE_OBJ_NAME,
"vmt_guid");
// instance-types - vm template network interface
addJoin(SearchObjects.INSTANCE_TYPE_OBJ_NAME,
"vmt_guid",
SearchObjects.VM_NETWORK_INTERFACE_OBJ_NAME,
"vmt_guid");
// vds - storage domain
addJoin(SearchObjects.VDS_OBJ_NAME,
"storage_id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// cluster - storage domain
addJoin(SearchObjects.VDC_CLUSTER_OBJ_NAME,
"storage_id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// disk - storage domain images
addJoin(SearchObjects.DISK_OBJ_NAME,
"image_guid",
SearchObjects.VDC_STORAGE_DOMAIN_IMAGE_OBJ_NAME,
"image_guid");
// storage domain images - storage domain
addJoin(SearchObjects.VDC_STORAGE_DOMAIN_IMAGE_OBJ_NAME,
"id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"id");
// vds - audit
addJoin(SearchObjects.VDS_OBJ_NAME,
"vds_id",
SearchObjects.AUDIT_OBJ_NAME,
"vds_id");
// users - audit
addJoin(SearchObjects.VDC_USER_OBJ_NAME,
"user_id",
SearchObjects.AUDIT_OBJ_NAME,
"user_id");
// Datacenter(Storage_pool) - Cluster(vds group)
addJoin(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME,
"id",
SearchObjects.VDC_CLUSTER_OBJ_NAME,
"storage_pool_id");
// Datacenter(Storage_pool) - Storage Domain
addJoin(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME,
"id",
SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
"storage_pool_id");
// Datacenter(Storage_pool) - Disk
addJoin(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME,
"id",
SearchObjects.DISK_OBJ_NAME,
"storage_pool_id");
// audit - cluster
addJoin(SearchObjects.VDC_CLUSTER_OBJ_NAME,
"cluster_id",
SearchObjects.AUDIT_OBJ_NAME,
"cluster_id");
// gluster volume - cluster
addJoin(SearchObjects.GLUSTER_VOLUME_OBJ_NAME,
"cluster_id",
SearchObjects.VDC_CLUSTER_OBJ_NAME,
"cluster_id");
// cluster - network
addJoin(SearchObjects.VDC_CLUSTER_OBJ_NAME,
"cluster_id",
SearchObjects.NETWORK_CLUSTER_OBJ_NAME,
"cluster_id");
// network - cluster
addJoin(SearchObjects.NETWORK_OBJ_NAME,
"id",
SearchObjects.NETWORK_CLUSTER_OBJ_NAME,
"network_id");
// network - host
addJoin(SearchObjects.NETWORK_OBJ_NAME,
"id",
SearchObjects.NETWORK_HOST_OBJ_NAME,
"network_id");
// audit - gluster volume
addJoin(SearchObjects.GLUSTER_VOLUME_OBJ_NAME,
"id",
SearchObjects.AUDIT_OBJ_NAME,
"gluster_volume_id");
// quota - audit
addJoin(SearchObjects.AUDIT_OBJ_NAME,
"quota_id",
SearchObjects.QUOTA_OBJ_NAME,
"quota_id");
// data center - network
addJoin(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME,
"id",
SearchObjects.NETWORK_OBJ_NAME,
"storage_pool_id");
// host interface - host
addJoin(SearchObjects.VDS_OBJ_NAME,
"vds_id",
SearchObjects.VDS_NETWORK_INTERFACE_OBJ_NAME,
"vds_id");
// cluster - vm pool
addJoin(SearchObjects.VDC_CLUSTER_OBJ_NAME,
"cluster_id",
SearchObjects.VDC_POOL_OBJ_NAME,
"cluster_id");
// provider - network
addJoin(SearchObjects.PROVIDER_OBJ_NAME,
"id",
SearchObjects.NETWORK_OBJ_NAME,
"provider_network_provider_id");
// users - template
addJoin(SearchObjects.VDC_USER_OBJ_NAME,
"vm_guid",
SearchObjects.TEMPLATE_OBJ_NAME,
"vmt_guid");
// users - host
addJoin(SearchObjects.VDC_USER_OBJ_NAME,
"vm_guid",
SearchObjects.VDS_OBJ_NAME,
"vds_id");
}
private void addJoin(String firstObj, String firstColumnName, String secondObj, String secondColumnName) {
joinDictionary.put(firstObj + "." + secondObj, new String[] { firstColumnName, secondColumnName });
joinDictionary.put(secondObj + "." + firstObj, new String[] { secondColumnName, firstColumnName });
}
public static final class EntitySearchInfo {
public EntitySearchInfo(IAutoCompleter crossRefAutoCompleter,
IConditionFieldAutoCompleter conditionFieldAutoCompleter,
String relatedTableNameWithOutTags,
String relatedTableName,
String primeryKeyName,
String defaultSort) {
this.crossRefAutoCompleter = crossRefAutoCompleter;
this.conditionFieldAutoCompleter = conditionFieldAutoCompleter;
this.relatedTableNameWithOutTags = relatedTableNameWithOutTags;
this.relatedTableName = relatedTableName;
this.primeryKeyName = primeryKeyName;
this.defaultSort = defaultSort;
}
public EntitySearchInfo(IAutoCompleter crossRefAutoCompleter,
IConditionFieldAutoCompleter conditionFieldAutoCompleter,
String relatedTableNameWithOutTags,
String relatedTableName,
String primeryKeyName,
String defaultSort,
List<String> commaDelimitedListColumns) {
this(crossRefAutoCompleter, conditionFieldAutoCompleter, relatedTableNameWithOutTags, relatedTableName, primeryKeyName, defaultSort);
this.commaDelimitedListColumns = commaDelimitedListColumns;
}
final IAutoCompleter crossRefAutoCompleter;
final IConditionFieldAutoCompleter conditionFieldAutoCompleter;
final String relatedTableNameWithOutTags;
final String relatedTableName;
final String primeryKeyName;
final String defaultSort;
List<String> commaDelimitedListColumns;
}
@SuppressWarnings("serial")
private static final Map<String, EntitySearchInfo> entitySearchInfo = Collections.unmodifiableMap(
new HashMap<String, SearchObjectAutoCompleter.EntitySearchInfo>() {
{
put(SearchObjects.AUDIT_OBJ_NAME, new EntitySearchInfo(new AuditCrossRefAutoCompleter(),
new AuditLogConditionFieldAutoCompleter(),
null,
"audit_log",
"audit_log_id",
"audit_log_id DESC "));
put(SearchObjects.TEMPLATE_OBJ_NAME, new EntitySearchInfo(new TemplateCrossRefAutoCompleter(),
new VmTemplateConditionFieldAutoCompleter(),
"vm_templates_view",
"vm_templates_storage_domain",
"vmt_guid",
"name ASC "));
put(SearchObjects.INSTANCE_TYPE_OBJ_NAME, new EntitySearchInfo(new TemplateCrossRefAutoCompleter(),
new VmTemplateConditionFieldAutoCompleter(),
"instance_types_view",
"instance_types_storage_domain",
"vmt_guid",
"name ASC "));
put(SearchObjects.IMAGE_TYPE_OBJ_NAME, new EntitySearchInfo(new TemplateCrossRefAutoCompleter(),
new VmTemplateConditionFieldAutoCompleter(),
"image_types_view",
"image_types_storage_domain",
"vmt_guid",
"name ASC "));
put(SearchObjects.VDC_USER_OBJ_NAME, new EntitySearchInfo(new UserCrossRefAutoCompleter(),
new VdcUserConditionFieldAutoCompleter(),
"vdc_users",
"vdc_users_with_tags",
"user_id",
"name ASC "));
put(SearchObjects.VDC_GROUP_OBJ_NAME, new EntitySearchInfo(
null,
new VdcGroupConditionFieldAutoCompleter(),
"ad_groups",
"ad_groups",
"id",
"name ASC "));
put(SearchObjects.VDS_OBJ_NAME, new EntitySearchInfo(new VdsCrossRefAutoCompleter(),
new VdsConditionFieldAutoCompleter(),
"vds",
"vds_with_tags",
"vds_id",
"vds_name ASC "));
put(SearchObjects.VM_OBJ_NAME, new EntitySearchInfo(new VmCrossRefAutoCompleter(),
new VmConditionFieldAutoCompleter(),
"vms",
"vms_with_tags",
"vm_guid",
"vm_name ASC "));
put(SearchObjects.VDC_CLUSTER_OBJ_NAME, new EntitySearchInfo(new ClusterCrossRefAutoCompleter(),
new ClusterConditionFieldAutoCompleter(),
"cluster_view",
"cluster_storage_domain",
"cluster_id",
"name ASC"));
put(SearchObjects.QUOTA_OBJ_NAME, new EntitySearchInfo(new QuotaConditionFieldAutoCompleter(),
new QuotaConditionFieldAutoCompleter(),
"quota_view",
"quota_view",
"quota_id",
"quota_name ASC"));
put(SearchObjects.VDC_STORAGE_POOL_OBJ_NAME,
new EntitySearchInfo(new StoragePoolCrossRefAutoCompleter(),
new StoragePoolFieldAutoCompleter(),
"storage_pool",
"storage_pool_with_storage_domain",
"id",
"name ASC "));
put(SearchObjects.DISK_OBJ_NAME, new EntitySearchInfo(new DiskCrossRefAutoCompleter(),
new DiskConditionFieldAutoCompleter(),
"all_disks",
"all_disks",
"disk_id",
"disk_alias ASC, disk_id ASC ",
Arrays.asList("vm_names")));
put(SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME,
new EntitySearchInfo(new StorageDomainCrossRefAutoCompleter(),
new StorageDomainFieldAutoCompleter(),
"storage_domains_for_search",
"storage_domains_with_hosts_view",
"id",
"storage_name ASC ",
Arrays.asList("datacenter")));
put(SearchObjects.VDC_STORAGE_DOMAIN_IMAGE_OBJ_NAME,
new EntitySearchInfo(null,
null,
null,
"vm_images_storage_domains_view",
"image_guid",
"disk_alias ASC, disk_id ASC "));
put(SearchObjects.GLUSTER_VOLUME_OBJ_NAME,
new EntitySearchInfo(GlusterVolumeCrossRefAutoCompleter.INSTANCE,
GlusterVolumeConditionFieldAutoCompleter.INSTANCE,
null,
"gluster_volumes_view",
"id",
"vol_name ASC "));
put(SearchObjects.VDC_POOL_OBJ_NAME, new EntitySearchInfo(null,
new PoolConditionFieldAutoCompleter(),
null,
"vm_pools_full_view",
"vm_pool_id",
"vm_pool_name ASC "));
put(SearchObjects.NETWORK_OBJ_NAME, new EntitySearchInfo(new NetworkCrossRefAutoCompleter(),
new NetworkConditionFieldAutoCompleter(),
"network_view",
"network_view",
"id",
"storage_pool_name ASC, name ASC"));
put(SearchObjects.VDS_NETWORK_INTERFACE_OBJ_NAME, new EntitySearchInfo(null,
new NetworkInterfaceConditionFieldAutoCompleter(),
"vds_interface",
"vds_interface",
"vds_id",
"name ASC"));
put(SearchObjects.VM_NETWORK_INTERFACE_OBJ_NAME, new EntitySearchInfo(null,
new NetworkInterfaceConditionFieldAutoCompleter(),
"vm_interface_view",
"vm_interface_view",
"name",
"vm_id ASC"));
put(SearchObjects.NETWORK_CLUSTER_OBJ_NAME,
new EntitySearchInfo(null,
new NetworkClusterConditionFieldAutoCompleter(),
"network_cluster_view",
"network_cluster_view",
"cluster_id",
"cluster_name ASC"));
put(SearchObjects.NETWORK_HOST_OBJ_NAME, new EntitySearchInfo(null,
new NetworkHostConditionFieldAutoCompleter(),
"network_vds_view",
"network_vds_view",
"vds_name",
"network_name ASC"));
put(SearchObjects.PROVIDER_OBJ_NAME, new EntitySearchInfo(null,
new ProviderConditionFieldAutoCompleter(),
"providers",
"providers",
"id",
"name ASC"));
put(SearchObjects.SESSION_OBJ_NAME, new EntitySearchInfo(null,
new SessionConditionFieldAutoCompleter(),
"engine_sessions",
"engine_sessions",
"id",
"user_name ASC, id"));
}
});
static EntitySearchInfo getEntitySearchInfo(String key) {
return entitySearchInfo.get(singular(key));
}
@SuppressWarnings("serial")
private static final Map<String, String> singulars = Collections.unmodifiableMap(new HashMap<String, String>() {
{
put(SearchObjects.AUDIT_PLU_OBJ_NAME, SearchObjects.AUDIT_OBJ_NAME);
put(SearchObjects.TEMPLATE_PLU_OBJ_NAME, SearchObjects.TEMPLATE_OBJ_NAME);
put(SearchObjects.INSTANCE_TYPE_PLU_OBJ_NAME, SearchObjects.INSTANCE_TYPE_OBJ_NAME);
put(SearchObjects.IMAGE_TYPE_PLU_OBJ_NAME, SearchObjects.IMAGE_TYPE_OBJ_NAME);
put(SearchObjects.VDC_USER_PLU_OBJ_NAME, SearchObjects.VDC_USER_OBJ_NAME);
put(SearchObjects.VDC_GROUP_PLU_OBJ_NAME, SearchObjects.VDC_GROUP_OBJ_NAME);
put(SearchObjects.VDS_PLU_OBJ_NAME, SearchObjects.VDS_OBJ_NAME);
put(SearchObjects.VM_PLU_OBJ_NAME, SearchObjects.VM_OBJ_NAME);
put(SearchObjects.VDC_CLUSTER_PLU_OBJ_NAME, SearchObjects.VDC_CLUSTER_OBJ_NAME);
put(SearchObjects.QUOTA_PLU_OBJ_NAME, SearchObjects.QUOTA_OBJ_NAME);
put(SearchObjects.DISK_PLU_OBJ_NAME, SearchObjects.DISK_OBJ_NAME);
put(SearchObjects.GLUSTER_VOLUME_PLU_OBJ_NAME, SearchObjects.GLUSTER_VOLUME_OBJ_NAME);
put(SearchObjects.VDC_POOL_PLU_OBJ_NAME, SearchObjects.VDC_POOL_OBJ_NAME);
put(SearchObjects.VDC_STORAGE_DOMAIN_PLU_OBJ_NAME, SearchObjects.VDC_STORAGE_DOMAIN_OBJ_NAME);
put(SearchObjects.NETWORK_PLU_OBJ_NAME, SearchObjects.NETWORK_OBJ_NAME);
put(SearchObjects.PROVIDER_PLU_OBJ_NAME, SearchObjects.PROVIDER_OBJ_NAME);
put(SearchObjects.SESSION_PLU_OBJ_NAME, SearchObjects.SESSION_OBJ_NAME);
}
});
static String singular(String key) {
return singulars.containsKey(key) ? singulars.get(key) : key;
}
public IAutoCompleter getCrossRefAutoCompleter(String obj) {
if (obj == null) {
return null;
}
if (getEntitySearchInfo(obj) != null) {
return getEntitySearchInfo(obj).crossRefAutoCompleter;
}
else {
return null;
}
}
public boolean isCrossReference(String text, String obj) {
IAutoCompleter completer = getCrossRefAutoCompleter(obj);
if (completer != null) {
return completer.validate(text);
}
return false;
}
public String getInnerJoin(String searchObj, String crossRefObj, boolean useTags) {
final String[] joinKey = joinDictionary.get(StringFormat.format("%1$s.%2$s", searchObj, crossRefObj));
// For joins, the table we join with is always the full view (including the tags)
final String crossRefTable = getRelatedTableName(crossRefObj, true);
final String searchObjTable = getRelatedTableName(searchObj, useTags);
return StringFormat.format(" LEFT OUTER JOIN %3$s ON %1$s.%2$s=%3$s.%4$s ", searchObjTable, joinKey[0],
crossRefTable, joinKey[1]);
}
public IConditionFieldAutoCompleter getFieldAutoCompleter(String obj) {
if (obj == null) {
return null;
}
if (getEntitySearchInfo(obj) != null) {
return getEntitySearchInfo(obj).conditionFieldAutoCompleter;
}
return null;
}
public String getRelatedTableName(String obj, String fieldName, boolean useTagsInFrom) {
return getRelatedTableName(obj, fieldName == null || fieldName.length() == 0
|| fieldName.toLowerCase().equalsIgnoreCase("tag")
|| requiresTagsForField(obj, fieldName, useTagsInFrom));
}
private boolean requiresTagsForField(String obj, String fieldName, boolean useTagsInFrom) {
if (useTagsInFrom) {
return requiresFullTable.containsKey(obj + "-" + fieldName);
}
return false;
}
public String getRelatedTableName(String obj, boolean useTags) {
if (useTags) {
return getRelatedTableName(obj);
}
return getRelatedTableNameWithoutTags(obj);
}
private String getRelatedTableNameWithoutTags(String obj) {
if (obj == null) {
return null;
} else if (getEntitySearchInfo(obj) != null && getEntitySearchInfo(obj).relatedTableNameWithOutTags != null) {
return getEntitySearchInfo(obj).relatedTableNameWithOutTags;
}
else {
return getRelatedTableName(obj);
}
}
private String getRelatedTableName(String obj) {
if (obj == null) {
return null;
} else if (getEntitySearchInfo(obj) != null) {
return getEntitySearchInfo(obj).relatedTableName;
}
return null;
}
public String getPrimeryKeyName(String obj) {
if (getEntitySearchInfo(obj) != null) {
return getEntitySearchInfo(obj).primeryKeyName;
}
return null;
}
public IAutoCompleter getFieldRelationshipAutoCompleter(String obj, String fieldName) {
IConditionFieldAutoCompleter curConditionFieldAC = getFieldAutoCompleter(obj);
if (curConditionFieldAC != null) {
return curConditionFieldAC.getFieldRelationshipAutoCompleter(fieldName);
}
return null;
}
public IAutoCompleter getObjectRelationshipAutoCompleter() {
return StringConditionRelationAutoCompleter.INSTANCE;
}
public IConditionValueAutoCompleter getFieldValueAutoCompleter(String obj, String fieldName) {
final IConditionFieldAutoCompleter curConditionFieldAC = getFieldAutoCompleter(obj);
if (curConditionFieldAC != null) {
return curConditionFieldAC.getFieldValueAutoCompleter(fieldName);
}
return null;
}
public String getDefaultSort(String obj) {
if (obj == null) {
return "";
}
if (getEntitySearchInfo(obj) != null) {
return getEntitySearchInfo(obj).defaultSort;
}
return "";
}
public List<String> getCommaDelimitedListColumns(String obj) {
return getEntitySearchInfo(obj).commaDelimitedListColumns;
}
}