/* * Copyright (c) 2010-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.component.search; import com.evolveum.midpoint.model.api.ModelInteractionService; import com.evolveum.midpoint.prism.*; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.schema.SchemaRegistry; import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.FullTextSearchConfigurationUtil; import com.evolveum.midpoint.schema.util.SystemConfigurationTypeUtil; import com.evolveum.midpoint.util.exception.ConfigurationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author Viliam Repan (lazyman) */ public class SearchFactory { private static final String DOT_CLASS = SearchFactory.class.getName() + "."; private static final String LOAD_OBJECT_DEFINITION = DOT_CLASS + "loadObjectDefinition"; private static final String LOAD_SYSTEM_CONFIGURATION = DOT_CLASS + "loadSystemConfiguration"; private static final String LOAD_ADMIN_GUI_CONFIGURATION = DOT_CLASS + "loadAdminGuiConfiguration"; private static final Map<Class, List<ItemPath>> SEARCHABLE_OBJECTS = new HashMap<>(); static { SEARCHABLE_OBJECTS.put(ObjectType.class, Arrays.asList( new ItemPath(ObjectType.F_NAME), new ItemPath(ObjectType.F_LIFECYCLE_STATE))); SEARCHABLE_OBJECTS.put(FocusType.class, Arrays.asList( new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_ADMINISTRATIVE_STATUS), new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_EFFECTIVE_STATUS))); SEARCHABLE_OBJECTS.put(UserType.class, Arrays.asList( new ItemPath(UserType.F_GIVEN_NAME), new ItemPath(UserType.F_FAMILY_NAME), new ItemPath(UserType.F_FULL_NAME), new ItemPath(UserType.F_ADDITIONAL_NAME), new ItemPath(UserType.F_COST_CENTER), new ItemPath(UserType.F_EMAIL_ADDRESS), new ItemPath(UserType.F_TELEPHONE_NUMBER), new ItemPath(UserType.F_EMPLOYEE_NUMBER), new ItemPath(UserType.F_EMPLOYEE_TYPE), new ItemPath(UserType.F_ORGANIZATIONAL_UNIT), new ItemPath(UserType.F_COST_CENTER), new ItemPath(UserType.F_LOCALITY))); SEARCHABLE_OBJECTS.put(RoleType.class, Arrays.asList( new ItemPath(RoleType.F_NAME), new ItemPath(RoleType.F_ROLE_TYPE))); SEARCHABLE_OBJECTS.put(ServiceType.class, Arrays.asList( new ItemPath(ServiceType.F_NAME), new ItemPath(ServiceType.F_SERVICE_TYPE), new ItemPath(ServiceType.F_URL))); SEARCHABLE_OBJECTS.put(ConnectorHostType.class, Arrays.asList( new ItemPath(ConnectorHostType.F_HOSTNAME) )); SEARCHABLE_OBJECTS.put(ConnectorType.class, Arrays.asList( new ItemPath(ConnectorType.F_CONNECTOR_BUNDLE), new ItemPath(ConnectorType.F_CONNECTOR_VERSION), new ItemPath(ConnectorType.F_CONNECTOR_TYPE) )); SEARCHABLE_OBJECTS.put(AbstractRoleType.class, Arrays.asList( new ItemPath(AbstractRoleType.F_IDENTIFIER), new ItemPath(AbstractRoleType.F_REQUESTABLE) )); SEARCHABLE_OBJECTS.put(OrgType.class, Arrays.asList( new ItemPath(OrgType.F_DISPLAY_NAME), new ItemPath(OrgType.F_COST_CENTER), new ItemPath(OrgType.F_ORG_TYPE), new ItemPath(OrgType.F_TENANT), new ItemPath(OrgType.F_LOCALITY) )); SEARCHABLE_OBJECTS.put(GenericObjectType.class, Arrays.asList( new ItemPath(GenericObjectType.F_OBJECT_TYPE) )); SEARCHABLE_OBJECTS.put(NodeType.class, Arrays.asList( new ItemPath(NodeType.F_NODE_IDENTIFIER) )); SEARCHABLE_OBJECTS.put(ReportType.class, Arrays.asList( new ItemPath(ReportType.F_PARENT) )); SEARCHABLE_OBJECTS.put(ShadowType.class, Arrays.asList( new ItemPath(ShadowType.F_OBJECT_CLASS), new ItemPath(ShadowType.F_DEAD), new ItemPath(ShadowType.F_INTENT), new ItemPath(ShadowType.F_EXISTS), new ItemPath(ShadowType.F_SYNCHRONIZATION_SITUATION), new ItemPath(ShadowType.F_FAILED_OPERATION_TYPE) )); SEARCHABLE_OBJECTS.put(TaskType.class, Arrays.asList( new ItemPath(TaskType.F_TASK_IDENTIFIER), new ItemPath(TaskType.F_NODE), new ItemPath(TaskType.F_CATEGORY), new ItemPath(TaskType.F_RESULT_STATUS) )); } public static <T extends ObjectType> Search createSearchForShadow( ResourceShadowDiscriminator discriminator, PrismContext ctx, ModelInteractionService modelInteractionService) { return createSearch(ShadowType.class, discriminator, ctx, modelInteractionService, true); } public static <T extends ObjectType> Search createSearch(Class<T> type, PrismContext ctx, ModelInteractionService modelInteractionService) { return createSearch(type, null, ctx, modelInteractionService, true); } public static <T extends ObjectType> Search createSearch( Class<T> type, ResourceShadowDiscriminator discriminator, PrismContext ctx, ModelInteractionService modelInteractionService, boolean useDefsFromSuperclass) { PrismObjectDefinition objectDef = findObjectDefinition(type, discriminator, ctx, modelInteractionService); Map<ItemPath, ItemDefinition> availableDefs = getAvailableDefinitions(objectDef, useDefsFromSuperclass); boolean isFullTextSearchEnabled = isFullTextSearchEnabled(modelInteractionService, type); Search search = new Search(type, availableDefs, isFullTextSearchEnabled, getDefaultSearchType(modelInteractionService, type)); SchemaRegistry registry = ctx.getSchemaRegistry(); PrismObjectDefinition objDef = registry.findObjectDefinitionByCompileTimeClass(ObjectType.class); PrismPropertyDefinition def = objDef.findPropertyDefinition(ObjectType.F_NAME); SearchItem item = search.addItem(def); if (item != null) { item.setFixed(true); } return search; } private static <T extends ObjectType> PrismObjectDefinition findObjectDefinition( Class<T> type, ResourceShadowDiscriminator discriminator, PrismContext ctx, ModelInteractionService modelInteractionService) { try { if (Modifier.isAbstract(type.getModifiers())) { SchemaRegistry registry = ctx.getSchemaRegistry(); return registry.findObjectDefinitionByCompileTimeClass(type); } OperationResult result = new OperationResult(LOAD_OBJECT_DEFINITION); PrismObject empty = ctx.createObject(type); if (ShadowType.class.equals(type)) { return modelInteractionService.getEditShadowDefinition(discriminator, AuthorizationPhaseType.REQUEST, result); } else { return modelInteractionService.getEditObjectDefinition( empty, AuthorizationPhaseType.REQUEST, result); } } catch (SchemaException | ConfigurationException | ObjectNotFoundException ex) { throw new SystemException(ex); } } private static <T extends ObjectType> Map<ItemPath, ItemDefinition> getAvailableDefinitions( PrismObjectDefinition<T> objectDef, boolean useDefsFromSuperclass) { Map<ItemPath, ItemDefinition> map = new HashMap<>(); map.putAll(createExtensionDefinitionList(objectDef)); Class<T> typeClass = objectDef.getCompileTimeClass(); while (typeClass != null && !com.evolveum.prism.xml.ns._public.types_3.ObjectType.class.equals(typeClass)) { List<ItemPath> paths = SEARCHABLE_OBJECTS.get(typeClass); if (paths != null) { for (ItemPath path : paths) { ItemDefinition def = objectDef.findItemDefinition(path); if (def != null) { map.put(path, def); } } } if (!useDefsFromSuperclass) { break; } typeClass = (Class<T>) typeClass.getSuperclass(); } return map; } private static <T extends ObjectType> boolean isFullTextSearchEnabled(ModelInteractionService modelInteractionService, Class<T> type) { OperationResult result = new OperationResult(LOAD_SYSTEM_CONFIGURATION); try { return FullTextSearchConfigurationUtil.isEnabledFor(modelInteractionService.getSystemConfiguration(result) .getFullTextSearch(), type); } catch (SchemaException | ObjectNotFoundException ex) { throw new SystemException(ex); } } private static <T extends ObjectType> SearchBoxModeType getDefaultSearchType (ModelInteractionService modelInteractionService, Class<T> type) { OperationResult result = new OperationResult(LOAD_ADMIN_GUI_CONFIGURATION); try { AdminGuiConfigurationType guiConfig = modelInteractionService.getAdminGuiConfiguration(null, result); if (guiConfig != null){ GuiObjectListsType objectLists = guiConfig.getObjectLists(); if (objectLists != null && objectLists.getObjectList() != null){ for (GuiObjectListType objectList : objectLists.getObjectList()){ if (objectList.getType() != null && type.getSimpleName().equals(objectList.getType().getLocalPart()) && objectList.getSearchBoxConfiguration() != null) { SearchBoxConfigurationType searchBoxConfig = objectList.getSearchBoxConfiguration(); return searchBoxConfig.getDefaultMode(); } } } } return null; } catch (SchemaException | ObjectNotFoundException ex) { throw new SystemException(ex); } } private static <T extends ObjectType> Map<ItemPath, ItemDefinition> createExtensionDefinitionList( PrismObjectDefinition<T> objectDef) { Map<ItemPath, ItemDefinition> map = new HashMap<>(); ItemPath extensionPath = new ItemPath(ObjectType.F_EXTENSION); PrismContainerDefinition ext = objectDef.findContainerDefinition(ObjectType.F_EXTENSION); for (ItemDefinition def : (List<ItemDefinition>) ext.getDefinitions()) { if (!(def instanceof PrismPropertyDefinition) && !(def instanceof PrismReferenceDefinition)) { continue; } map.put(new ItemPath(extensionPath, def.getName()), def); } return map; } }