Skip to content

Commit

Permalink
Subtree search for organizational units (MID-2472)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Oct 12, 2015
1 parent 52857b9 commit 0ef6838
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 21 deletions.
Expand Up @@ -24,6 +24,9 @@
<div class="row">
<div class="col-md-12 clearfix">
<form class="form-inline pull-right search-form" wicket:id="searchForm">
<div class="form-group">
<select class="form-control input-sm" wicket:id="searchScope"/>
</div>
<div wicket:id="basicSearch"/>
</form>
</div>
Expand Down
Expand Up @@ -64,6 +64,7 @@
import com.evolveum.midpoint.web.session.UserProfileStorage;
import com.evolveum.midpoint.web.util.ObjectTypeGuiDescriptor;
import com.evolveum.midpoint.web.util.OnePageParameterEncoder;
import com.evolveum.midpoint.web.util.StringResourceChoiceRenderer;
import com.evolveum.midpoint.web.util.WebMiscUtil;
import com.evolveum.midpoint.web.util.WebModelUtils;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
Expand All @@ -86,15 +87,18 @@
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -137,7 +141,12 @@ public class TreeTablePanel extends SimplePanel<String> {
private static final String ID_TREE_HEADER = "treeHeader";
private static final String ID_SEARCH_FORM = "searchForm";
private static final String ID_BASIC_SEARCH = "basicSearch";
private static final String ID_SEARCH_SCOPE = "searchScope";

private static final String SEARCH_SCOPE_SUBTREE = "subtree";
private static final String SEARCH_SCOPE_ONE = "one";
private static final List<String> SEARCH_SCOPE_VALUES = Arrays.asList( SEARCH_SCOPE_SUBTREE, SEARCH_SCOPE_ONE);

private IModel<OrgTreeDto> selected = new LoadableModel<OrgTreeDto>() {

@Override
Expand Down Expand Up @@ -405,7 +414,6 @@ public ObjectQuery getQuery() {
UserProfileStorage.TableId.TREE_TABLE_PANEL_MANAGER, UserProfileStorage.DEFAULT_PAGING_SIZE);
managerTablePanel.setOutputMarkupId(true);
managerTablePanel.getNavigatorPanel().add(new VisibleEnableBehaviour(){

@Override
public boolean isVisible() {
return managerTableProvider.size() > managerTablePanel.getDataTable().getItemsPerPage();
Expand Down Expand Up @@ -454,6 +462,11 @@ private void initSearch() {
Form form = new Form(ID_SEARCH_FORM);
form.setOutputMarkupId(true);
add(form);


DropDownChoice<String> seachScrope = new DropDownChoice<String>(ID_SEARCH_SCOPE, Model.of(SEARCH_SCOPE_SUBTREE),
SEARCH_SCOPE_VALUES, new StringResourceChoiceRenderer("TreeTablePanel.search.scope"));
form.add(seachScrope);

BasicSearchPanel basicSearch = new BasicSearchPanel(ID_BASIC_SEARCH, new Model()) {

Expand Down Expand Up @@ -1140,15 +1153,27 @@ private ObjectQuery createOrgChildQuery() {
OrgTreeDto dto = selected.getObject();
String oid = dto != null ? dto.getOid() : getModel().getObject();

OrgFilter org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);

BasicSearchPanel<String> basicSearch = (BasicSearchPanel) get(createComponentPath(ID_SEARCH_FORM, ID_BASIC_SEARCH));
String object = basicSearch.getModelObject();

if (StringUtils.isEmpty(object)) {
return ObjectQuery.createObjectQuery(org);
DropDownChoice<String> searchScopeChoice = (DropDownChoice) get(createComponentPath(ID_SEARCH_FORM, ID_SEARCH_SCOPE));
String scope = searchScopeChoice.getModelObject();

if (StringUtils.isBlank(object)) {
object = null;
}

OrgFilter org;
if (object == null || SEARCH_SCOPE_ONE.equals(scope)) {
org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);
} else {
org = OrgFilter.createOrg(oid, OrgFilter.Scope.SUBTREE);
}

if (object == null) {
return ObjectQuery.createObjectQuery(org);
}

PageBase page = getPageBase();
PrismContext context = page.getPrismContext();

Expand All @@ -1162,8 +1187,13 @@ private ObjectQuery createOrgChildQuery() {
PolyStringNormMatchingRule.NAME, normalizedString);

AndFilter and = AndFilter.createAnd(org, substring);
ObjectQuery query = ObjectQuery.createObjectQuery(and);

if(LOGGER.isTraceEnabled()){
LOGGER.trace("Searching child rgs of org {} with query:\n{}", oid, query.debugDump());
}

return ObjectQuery.createObjectQuery(and);
return query;
}

private ObjectQuery createManagerTableQuery(){
Expand All @@ -1184,9 +1214,17 @@ private ObjectQuery createManagerTableQuery(){
substring = SubstringFilter.createSubstring(ObjectType.F_NAME, ObjectType.class, getPageBase().getPrismContext(),
PolyStringNormMatchingRule.NAME, normalizedString);
}

DropDownChoice<String> searchScopeChoice = (DropDownChoice) get(createComponentPath(ID_SEARCH_FORM, ID_SEARCH_SCOPE));
String scope = searchScopeChoice.getModelObject();

try {
OrgFilter org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);
OrgFilter org;
if (substring == null || SEARCH_SCOPE_ONE.equals(scope)) {
org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);
} else {
org = OrgFilter.createOrg(oid, OrgFilter.Scope.SUBTREE);
}

PrismReferenceValue referenceValue = new PrismReferenceValue();
referenceValue.setOid(oid);
Expand Down Expand Up @@ -1220,30 +1258,46 @@ private ObjectQuery createMemberQuery(){
PolyStringNormalizer normalizer = getPageBase().getPrismContext().getDefaultPolyStringNormalizer();
String normalizedString = normalizer.normalize(object);

if (StringUtils.isEmpty(normalizedString)) {
if (StringUtils.isBlank(normalizedString)) {
substring = null;
} else {
substring = SubstringFilter.createSubstring(ObjectType.F_NAME, ObjectType.class, getPageBase().getPrismContext(),
PolyStringNormMatchingRule.NAME, normalizedString);
}

try {
OrgFilter org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);

PrismReferenceValue referenceFilter = new PrismReferenceValue();
referenceFilter.setOid(oid);
referenceFilter.setRelation(null);
RefFilter referenceOidFilter = RefFilter.createReferenceEqual(new ItemPath(FocusType.F_PARENT_ORG_REF),
UserType.class, getPageBase().getPrismContext(), referenceFilter);
DropDownChoice<String> searchScopeChoice = (DropDownChoice) get(createComponentPath(ID_SEARCH_FORM, ID_SEARCH_SCOPE));
String scope = searchScopeChoice.getModelObject();

if(substring != null){
query = ObjectQuery.createObjectQuery(AndFilter.createAnd(org, referenceOidFilter , substring));
try {
OrgFilter org;
if (substring == null || SEARCH_SCOPE_ONE.equals(scope)) {
org = OrgFilter.createOrg(oid, OrgFilter.Scope.ONE_LEVEL);

PrismReferenceValue referenceFilter = new PrismReferenceValue();
referenceFilter.setOid(oid);
referenceFilter.setRelation(null);
RefFilter referenceOidFilter = RefFilter.createReferenceEqual(new ItemPath(FocusType.F_PARENT_ORG_REF),
UserType.class, getPageBase().getPrismContext(), referenceFilter);

if (substring != null){
query = ObjectQuery.createObjectQuery(AndFilter.createAnd(org, referenceOidFilter , substring));
} else {
query = ObjectQuery.createObjectQuery(AndFilter.createAnd(org, referenceOidFilter));
}

} else {
query = ObjectQuery.createObjectQuery(AndFilter.createAnd(org, referenceOidFilter));

org = OrgFilter.createOrg(oid, OrgFilter.Scope.SUBTREE);

if (substring != null){
query = ObjectQuery.createObjectQuery(AndFilter.createAnd(org, substring));
} else {
query = ObjectQuery.createObjectQuery(org);
}
}

if(LOGGER.isTraceEnabled()){
LOGGER.info(query.debugDump());
LOGGER.trace("Searching members of org {} with query:\n{}", oid, query.debugDump());
}

} catch (SchemaException e) {
Expand Down
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2015 Evolveum
*
* 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 com.evolveum.midpoint.web.util;

import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.ResourceModel;

/**
* @author semancik
*
*/
public class StringResourceChoiceRenderer implements IChoiceRenderer<String> {
private static final long serialVersionUID = 1L;

String keyPrefix;

public StringResourceChoiceRenderer(String keyPrefix) {
super();
this.keyPrefix = keyPrefix;
}

@Override
public Object getDisplayValue(String object) {
return new ResourceModel(keyPrefix+"."+object, object).getObject();
}

@Override
public String getIdValue(String object, int index) {
return object;
}

}
Expand Up @@ -2651,6 +2651,8 @@ TreeTablePanel.message.recomputeError=Can't recompute Org. unit
TreeTablePanel.moveRoot=Move root
TreeTablePanel.recomputeRoot=Recompute root
TreeTablePanel.recomputeTask=Recompute users in organization {0}
TreeTablePanel.search.scope.one=One level
TreeTablePanel.search.scope.subtree=Subtree
Type.AUDIT=Audit
type.nullValid=Choose One
Type.RECONCILIATION=Reconciliation
Expand Down
Expand Up @@ -220,7 +220,6 @@ public String debugDump(int indent) {
if (anchorEnd) {
sb.append(" anchorEnd");
}
sb.append("\n");
return debugDump(indent, sb);
}

Expand Down

0 comments on commit 0ef6838

Please sign in to comment.