private void AddGrouped(IXenObject o, Object group) { // We sometimes need to apply the query to the group. For example, suppose VM 1 // is connected to Network 1 and Network 2. Then "VMs grouped by Network" will // show // // -- Network 1 // -- VM 1 // -- Network 2 // -- VM 1 // // So far so good. Now consider "VMs connected to Network 1 grouped by Network". // Without the following piece of code, that would show exactly the same thing: // because the second VM 1 is connected to Network 1, and is correctly grouped // in Network 2. But what the user presumably wanted to see was just Network 1 // with its VMs under it: and that is achieved by applying the filter to the // networks. // // The consequence when adding new searches is that a search that returns a // XenObject of type T must return (T)o rather than null when o is a T, // otherwise if you both group and filter by that type, the group will fail // to match the filter and you'll get no results. // IXenObject groupModelObject = group as IXenObject; if (groupModelObject != null && XenAdminConfigManager.Provider.ObjectIsHidden(groupModelObject.opaque_ref)) { return; } if (search.Query != null && groupModelObject != null) { QueryFilter subquery = grouping.GetRelevantGroupQuery(search); if (subquery != null && subquery.Match(groupModelObject) == false) { return; } } Group nextGroup; // Some types of grouping can add several levels to the hierarchy. // This should not be confused with the IList in Add(IXenObject o): // that adds the item to several groups, whereas this adds it to a // single group several levels deep. In order to reach here, // grouping.GetGroup(o) must return a list of arrays. // // NB We don't do the GetRelevantGroupQuery() check as above for the // groups added in this way because we never need it: but if we ever // add it, we should probably do a first pass to check all the groups // first before adding any. Array groups = group as Array; if (groups != null) { nextGroup = this; for (int i = 0; i < groups.Length; ++i) { Grouping gr = (i == groups.Length - 1 ? grouping.subgrouping : grouping); nextGroup = (nextGroup as AbstractNodeGroup).FindOrAddSubgroup(grouping, groups.GetValue(i), gr); } } else { nextGroup = FindOrAddSubgroup(grouping, group, grouping.subgrouping); } nextGroup.Add(o); }
public bool Match(IXenObject o) { return(scope.WantType(o) && o.Show(XenAdminConfigManager.Provider.ShowHiddenVMs) && (filter == null || filter.Match(o) != false)); }