/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.core.context.mgr; import com.espertech.esper.client.EventBean; import com.espertech.esper.client.context.*; import com.espertech.esper.core.context.util.ContextControllerSelectorUtil; import com.espertech.esper.epl.spec.ContextDetailCategoryItem; import java.util.LinkedHashMap; import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; public class ContextControllerCategory implements ContextController { private final int pathId; private final ContextControllerLifecycleCallback activationCallback; private final ContextControllerCategoryFactoryImpl factory; private final Map<Integer, ContextControllerInstanceHandle> handleCategories = new LinkedHashMap<Integer, ContextControllerInstanceHandle>(); private int currentSubpathId; public ContextControllerCategory(int pathId, ContextControllerLifecycleCallback activationCallback, ContextControllerCategoryFactoryImpl factory) { this.pathId = pathId; this.activationCallback = activationCallback; this.factory = factory; } public void importContextPartitions(ContextControllerState state, int pathIdToUse, ContextInternalFilterAddendum filterAddendum, AgentInstanceSelector agentInstanceSelector) { initializeFromState(null, null, filterAddendum, state, pathIdToUse, agentInstanceSelector, true); } public void deletePath(ContextPartitionIdentifier identifier) { ContextPartitionIdentifierCategory category = (ContextPartitionIdentifierCategory) identifier; int count = 0; for (ContextDetailCategoryItem cat : factory.getCategorySpec().getItems()) { if (cat.getName().equals(category.getLabel())) { handleCategories.remove(count); break; } count++; } } public void visitSelectedPartitions(ContextPartitionSelector contextPartitionSelector, ContextPartitionVisitor visitor) { int nestingLevel = factory.getFactoryContext().getNestingLevel(); if (contextPartitionSelector instanceof ContextPartitionSelectorFiltered) { ContextPartitionSelectorFiltered filter = (ContextPartitionSelectorFiltered) contextPartitionSelector; ContextPartitionIdentifierCategory identifier = new ContextPartitionIdentifierCategory(); for (Map.Entry<Integer, ContextControllerInstanceHandle> entry : handleCategories.entrySet()) { identifier.setContextPartitionId(entry.getValue().getContextPartitionOrPathId()); String categoryName = factory.getCategorySpec().getItems().get(entry.getKey()).getName(); identifier.setLabel(categoryName); if (filter.filter(identifier)) { visitor.visit(nestingLevel, pathId, factory.getBinding(), entry.getKey(), this, entry.getValue()); } } return; } if (contextPartitionSelector instanceof ContextPartitionSelectorCategory) { ContextPartitionSelectorCategory category = (ContextPartitionSelectorCategory) contextPartitionSelector; if (category.getLabels() == null || category.getLabels().isEmpty()) { return; } for (Map.Entry<Integer, ContextControllerInstanceHandle> entry : handleCategories.entrySet()) { String categoryName = factory.getCategorySpec().getItems().get(entry.getKey()).getName(); if (category.getLabels().contains(categoryName)) { visitor.visit(nestingLevel, pathId, factory.getBinding(), entry.getKey(), this, entry.getValue()); } } return; } if (contextPartitionSelector instanceof ContextPartitionSelectorById) { ContextPartitionSelectorById byId = (ContextPartitionSelectorById) contextPartitionSelector; for (Map.Entry<Integer, ContextControllerInstanceHandle> entry : handleCategories.entrySet()) { int cpid = entry.getValue().getContextPartitionOrPathId(); if (byId.getContextPartitionIds().contains(cpid)) { visitor.visit(nestingLevel, pathId, factory.getBinding(), entry.getKey(), this, entry.getValue()); } } return; } if (contextPartitionSelector instanceof ContextPartitionSelectorAll) { for (Map.Entry<Integer, ContextControllerInstanceHandle> entry : handleCategories.entrySet()) { String categoryName = factory.getCategorySpec().getItems().get(entry.getKey()).getName(); visitor.visit(nestingLevel, pathId, factory.getBinding(), entry.getKey(), this, entry.getValue()); } return; } throw ContextControllerSelectorUtil.getInvalidSelector(new Class[]{ContextPartitionSelectorCategory.class}, contextPartitionSelector); } public void activate(EventBean optionalTriggeringEvent, Map<String, Object> optionalTriggeringPattern, ContextControllerState controllerState, ContextInternalFilterAddendum activationFilterAddendum, Integer importPathId) { if (factory.getFactoryContext().getNestingLevel() == 1) { controllerState = ContextControllerStateUtil.getRecoveryStates(factory.getFactoryContext().getStateCache(), factory.getFactoryContext().getOutermostContextName()); } if (controllerState == null) { int count = 0; for (ContextDetailCategoryItem category : factory.getCategorySpec().getItems()) { Map<String, Object> context = ContextPropertyEventType.getCategorizedBean(factory.getFactoryContext().getContextName(), 0, category.getName()); currentSubpathId++; // merge filter addendum, if any ContextInternalFilterAddendum filterAddendumToUse = activationFilterAddendum; if (factory.hasFiltersSpecsNestedContexts()) { filterAddendumToUse = activationFilterAddendum != null ? activationFilterAddendum.deepCopy() : new ContextInternalFilterAddendum(); factory.populateContextInternalFilterAddendums(filterAddendumToUse, count); } ContextControllerInstanceHandle handle = activationCallback.contextPartitionInstantiate(null, currentSubpathId, null, this, optionalTriggeringEvent, optionalTriggeringPattern, count, context, controllerState, filterAddendumToUse, factory.getFactoryContext().isRecoveringResilient(), ContextPartitionState.STARTED); handleCategories.put(count, handle); factory.getFactoryContext().getStateCache().addContextPath(factory.getFactoryContext().getOutermostContextName(), factory.getFactoryContext().getNestingLevel(), pathId, currentSubpathId, handle.getContextPartitionOrPathId(), count, factory.getBinding()); count++; } return; } int pathIdToUse = importPathId != null ? importPathId : pathId; initializeFromState(optionalTriggeringEvent, optionalTriggeringPattern, activationFilterAddendum, controllerState, pathIdToUse, null, false); } public ContextControllerFactory getFactory() { return factory; } public int getPathId() { return pathId; } public void deactivate() { handleCategories.clear(); } private void initializeFromState(EventBean optionalTriggeringEvent, Map<String, Object> optionalTriggeringPattern, ContextInternalFilterAddendum activationFilterAddendum, ContextControllerState controllerState, int pathIdToUse, AgentInstanceSelector agentInstanceSelector, boolean loadingExistingState) { TreeMap<ContextStatePathKey, ContextStatePathValue> states = controllerState.getStates(); NavigableMap<ContextStatePathKey, ContextStatePathValue> childContexts = ContextControllerStateUtil.getChildContexts(factory.getFactoryContext(), pathIdToUse, states); int maxSubpathId = Integer.MIN_VALUE; for (Map.Entry<ContextStatePathKey, ContextStatePathValue> entry : childContexts.entrySet()) { int categoryNumber = (Integer) factory.getBinding().byteArrayToObject(entry.getValue().getBlob(), null); ContextDetailCategoryItem category = factory.getCategorySpec().getItems().get(categoryNumber); // merge filter addendum, if any ContextInternalFilterAddendum filterAddendumToUse = activationFilterAddendum; if (factory.hasFiltersSpecsNestedContexts()) { filterAddendumToUse = activationFilterAddendum != null ? activationFilterAddendum.deepCopy() : new ContextInternalFilterAddendum(); factory.populateContextInternalFilterAddendums(filterAddendumToUse, categoryNumber); } // check if exists already if (controllerState.isImported()) { ContextControllerInstanceHandle existingHandle = handleCategories.get(categoryNumber); if (existingHandle != null) { activationCallback.contextPartitionNavigate(existingHandle, this, controllerState, entry.getValue().getOptionalContextPartitionId(), filterAddendumToUse, agentInstanceSelector, entry.getValue().getBlob(), loadingExistingState); continue; } } Map<String, Object> context = ContextPropertyEventType.getCategorizedBean(factory.getFactoryContext().getContextName(), 0, category.getName()); int contextPartitionId = entry.getValue().getOptionalContextPartitionId(); int assignedSubPathId = !controllerState.isImported() ? entry.getKey().getSubPath() : ++currentSubpathId; ContextControllerInstanceHandle handle = activationCallback.contextPartitionInstantiate(contextPartitionId, assignedSubPathId, entry.getKey().getSubPath(), this, null, null, categoryNumber, context, controllerState, filterAddendumToUse, loadingExistingState || factory.getFactoryContext().isRecoveringResilient(), entry.getValue().getState()); handleCategories.put(categoryNumber, handle); if (entry.getKey().getSubPath() > maxSubpathId) { maxSubpathId = assignedSubPathId; } } if (!controllerState.isImported()) { currentSubpathId = maxSubpathId != Integer.MIN_VALUE ? maxSubpathId : 0; } } }