/** * Ctor. * * @param typeName is the event type name * @param eventType is the event type of the wrapped events * @param properties is the additional properties this wrapper adds * @param metadata event type metadata * @param eventAdapterService is the service for resolving unknown wrapped types */ public WrapperEventType( EventTypeMetadata metadata, String typeName, int eventTypeId, EventType eventType, Map<String, Object> properties, EventAdapterService eventAdapterService) { checkForRepeatedPropertyNames(eventType, properties); this.metadata = metadata; this.underlyingEventType = eventType; EventTypeMetadata metadataMapType = EventTypeMetadata.createAnonymous(typeName); this.underlyingMapType = new MapEventType( metadataMapType, typeName, 0, eventAdapterService, properties, null, null, null); this.isNoMapProperties = properties.isEmpty(); this.eventAdapterService = eventAdapterService; this.eventTypeId = eventTypeId; propertyGetterCache = new HashMap<String, EventPropertyGetter>(); updatePropertySet(); if (metadata.getTypeClass() == EventTypeMetadata.TypeClass.NAMED_WINDOW) { startTimestampPropertyName = eventType.getStartTimestampPropertyName(); endTimestampPropertyName = eventType.getEndTimestampPropertyName(); EventTypeUtility.validateTimestampProperties( this, startTimestampPropertyName, endTimestampPropertyName); } }
public Class getPropertyType(String property) { if (underlyingEventType.isProperty(property)) { return underlyingEventType.getPropertyType(property); } else if (underlyingMapType.isProperty(property)) { return underlyingMapType.getPropertyType(property); } else { return null; } }
public FragmentEventType getFragmentType(String property) { FragmentEventType fragment = underlyingEventType.getFragmentType(property); if (fragment != null) { return fragment; } return underlyingMapType.getFragmentType(property); }
public EventPropertyGetterIndexed getGetterIndexed(String indexedProperty) { final EventPropertyGetterIndexed undIndexed = underlyingEventType.getGetterIndexed(indexedProperty); if (undIndexed != null) { return new EventPropertyGetterIndexed() { public Object get(EventBean theEvent, int index) throws PropertyAccessException { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; EventBean wrappedEvent = wrapperEvent.getUnderlyingEvent(); if (wrappedEvent == null) { return null; } return undIndexed.get(wrappedEvent, index); } }; } final EventPropertyGetterIndexed decoIndexed = underlyingMapType.getGetterIndexed(indexedProperty); if (decoIndexed != null) { return new EventPropertyGetterIndexed() { public Object get(EventBean theEvent, int index) throws PropertyAccessException { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; Map map = wrapperEvent.getDecoratingProperties(); return decoIndexed.get( eventAdapterService.adapterForTypedMap(map, underlyingMapType), index); } }; } return null; }
private void updatePropertySet() { PropertyDescriptorComposite compositeProperties = getCompositeProperties(underlyingEventType, underlyingMapType); propertyNames = compositeProperties.getPropertyNames(); propertyDescriptorMap = compositeProperties.getPropertyDescriptorMap(); propertyDesc = compositeProperties.getDescriptors(); numPropertiesUnderlyingType = underlyingEventType.getPropertyDescriptors().length; }
public void testConfiguredViaPropsAndXML() { Configuration configuration = SupportConfigFactory.getConfiguration(); configuration .getEngineDefaults() .getEventMeta() .setDefaultEventRepresentation(Configuration.EventRepresentation.OBJECTARRAY); configuration.addEventType( "MyOAType", "bean,theString,map".split(","), new Object[] {SupportBean.class.getName(), "string", "java.util.Map"}); EPServiceProvider epService = EPServiceProviderManager.getDefaultProvider(configuration); epService.initialize(); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.startTest(epService, this.getClass(), getName()); } EventType eventType = epService.getEPAdministrator().getConfiguration().getEventType("MyOAType"); assertEquals(Object[].class, eventType.getUnderlyingType()); assertEquals(String.class, eventType.getPropertyType("theString")); assertEquals(Map.class, eventType.getPropertyType("map")); assertEquals(SupportBean.class, eventType.getPropertyType("bean")); EPStatement stmt = epService .getEPAdministrator() .createEPL("select bean, theString, map('key'), bean.theString from MyOAType"); SupportUpdateListener listener = new SupportUpdateListener(); stmt.addListener(listener); assertEquals(Object[].class, stmt.getEventType().getUnderlyingType()); SupportBean bean = new SupportBean("E1", 1); epService .getEPRuntime() .sendEvent( new Object[] {bean, "abc", Collections.singletonMap("key", "value")}, "MyOAType"); EPAssertionUtil.assertProps( listener.assertOneGetNew(), "bean,theString,map('key'),bean.theString".split(","), new Object[] {bean, "abc", "value", "E1"}); if (InstrumentationHelper.ENABLED) { InstrumentationHelper.endTest(); } }
private void checkForRepeatedPropertyNames(EventType eventType, Map<String, Object> properties) { for (String property : eventType.getPropertyNames()) { if (properties.keySet().contains(property)) { throw new EPException( "Property " + property + " occurs in both the underlying event and in the additional properties"); } } }
public Class getUnderlyingType() { // If the additional properties are empty, such as when wrapping a native event by means of // wildcard-only select // then the underlying type is simply the wrapped type. if (isNoMapProperties) { return underlyingEventType.getUnderlyingType(); } else { return Pair.class; } }
private static PropertyDescriptorComposite getCompositeProperties( EventType underlyingEventType, MapEventType underlyingMapType) { List<String> propertyNames = new ArrayList<String>(); propertyNames.addAll(Arrays.asList(underlyingEventType.getPropertyNames())); propertyNames.addAll(Arrays.asList(underlyingMapType.getPropertyNames())); String[] propertyNamesArr = propertyNames.toArray(new String[propertyNames.size()]); List<EventPropertyDescriptor> propertyDesc = new ArrayList<EventPropertyDescriptor>(); HashMap<String, EventPropertyDescriptor> propertyDescriptorMap = new HashMap<String, EventPropertyDescriptor>(); for (EventPropertyDescriptor eventProperty : underlyingEventType.getPropertyDescriptors()) { propertyDesc.add(eventProperty); propertyDescriptorMap.put(eventProperty.getPropertyName(), eventProperty); } for (EventPropertyDescriptor mapProperty : underlyingMapType.getPropertyDescriptors()) { propertyDesc.add(mapProperty); propertyDescriptorMap.put(mapProperty.getPropertyName(), mapProperty); } EventPropertyDescriptor[] propertyDescArr = propertyDesc.toArray(new EventPropertyDescriptor[propertyDesc.size()]); return new PropertyDescriptorComposite( propertyDescriptorMap, propertyNamesArr, propertyDescArr); }
public SelectExprProcessor getEvaluator() throws ExprValidationException { // Get the named and un-named stream selectors (i.e. select s0.* from S0 as s0), if any List<SelectClauseStreamCompiledSpec> namedStreams = new ArrayList<SelectClauseStreamCompiledSpec>(); List<SelectExprStreamDesc> unnamedStreams = new ArrayList<SelectExprStreamDesc>(); for (SelectExprStreamDesc spec : selectedStreams) { if (spec.getStreamSelected() != null && spec.getStreamSelected().getOptionalName() == null) { unnamedStreams.add(spec); } else if (spec.getExpressionSelectedAsStream() != null) { // handle special "transpose(...)" function unnamedStreams.add(spec); } else { namedStreams.add(spec.getStreamSelected()); if (spec.getStreamSelected().isProperty()) { throw new ExprValidationException( "The property wildcard syntax must be used without column name"); } } } // Error if there are more then one un-named streams (i.e. select s0.*, s1.* from S0 as s0, S1 // as s1) // Thus there is only 1 unnamed stream selector maximum. if (unnamedStreams.size() > 1) { throw new ExprValidationException( "A column name must be supplied for all but one stream if multiple streams are selected via the stream.* notation"); } if (selectedStreams.isEmpty() && selectionList.isEmpty() && !isUsingWildcard) { throw new IllegalArgumentException("Empty selection list not supported"); } for (SelectClauseExprCompiledSpec entry : selectionList) { if (entry.getAssignedName() == null) { throw new IllegalArgumentException( "Expected name for each expression has not been supplied"); } } // Verify insert into clause if (insertIntoDesc != null) { verifyInsertInto(insertIntoDesc, selectionList); } // Build a subordinate wildcard processor for joins SelectExprProcessor joinWildcardProcessor = null; if (typeService.getStreamNames().length > 1 && isUsingWildcard) { joinWildcardProcessor = SelectExprJoinWildcardProcessorFactory.create( assignedTypeNumberStack, statementId, typeService.getStreamNames(), typeService.getEventTypes(), eventAdapterService, null, selectExprEventTypeRegistry, methodResolutionService, annotations, configuration); } // Resolve underlying event type in the case of wildcard select EventType eventType = null; boolean singleStreamWrapper = false; if (isUsingWildcard) { if (joinWildcardProcessor != null) { eventType = joinWildcardProcessor.getResultEventType(); } else { eventType = typeService.getEventTypes()[0]; if (eventType instanceof WrapperEventType) { singleStreamWrapper = true; } } } // Get expression nodes ExprEvaluator[] exprEvaluators = new ExprEvaluator[selectionList.size()]; ExprNode[] exprNodes = new ExprNode[selectionList.size()]; Object[] expressionReturnTypes = new Object[selectionList.size()]; for (int i = 0; i < selectionList.size(); i++) { ExprNode expr = selectionList.get(i).getSelectExpression(); exprNodes[i] = expr; exprEvaluators[i] = expr.getExprEvaluator(); Map<String, Object> eventTypeExpr = exprEvaluators[i].getEventType(); if (eventTypeExpr == null) { expressionReturnTypes[i] = exprEvaluators[i].getType(); } else { final ExprEvaluator innerExprEvaluator = expr.getExprEvaluator(); final EventType mapType = eventAdapterService.createAnonymousMapType( statementId + "_innereval_" + CollectionUtil.toString(assignedTypeNumberStack, "_") + "_" + i, eventTypeExpr); ExprEvaluator evaluatorFragment = new ExprEvaluator() { public Object evaluate( EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { Map<String, Object> values = (Map<String, Object>) innerExprEvaluator.evaluate( eventsPerStream, isNewData, exprEvaluatorContext); if (values == null) { values = Collections.emptyMap(); } return eventAdapterService.adapterForTypedMap(values, mapType); } public Class getType() { return Map.class; } public Map<String, Object> getEventType() { return null; } }; expressionReturnTypes[i] = mapType; exprEvaluators[i] = evaluatorFragment; } } // Get column names String[] columnNames; String[] columnNamesAsProvided; if ((insertIntoDesc != null) && (!insertIntoDesc.getColumnNames().isEmpty())) { columnNames = insertIntoDesc .getColumnNames() .toArray(new String[insertIntoDesc.getColumnNames().size()]); columnNamesAsProvided = columnNames; } else if (!selectedStreams.isEmpty()) { // handle stream selection column names int numStreamColumnsJoin = 0; if (isUsingWildcard && typeService.getEventTypes().length > 1) { numStreamColumnsJoin = typeService.getEventTypes().length; } columnNames = new String[selectionList.size() + namedStreams.size() + numStreamColumnsJoin]; columnNamesAsProvided = new String[columnNames.length]; int count = 0; for (SelectClauseExprCompiledSpec aSelectionList : selectionList) { columnNames[count] = aSelectionList.getAssignedName(); columnNamesAsProvided[count] = aSelectionList.getProvidedName(); count++; } for (SelectClauseStreamCompiledSpec aSelectionList : namedStreams) { columnNames[count] = aSelectionList.getOptionalName(); columnNamesAsProvided[count] = aSelectionList.getOptionalName(); count++; } // for wildcard joins, add the streams themselves if (isUsingWildcard && typeService.getEventTypes().length > 1) { for (String streamName : typeService.getStreamNames()) { columnNames[count] = streamName; columnNamesAsProvided[count] = streamName; count++; } } } else // handle regular column names { columnNames = new String[selectionList.size()]; columnNamesAsProvided = new String[selectionList.size()]; for (int i = 0; i < selectionList.size(); i++) { columnNames[i] = selectionList.get(i).getAssignedName(); columnNamesAsProvided[i] = selectionList.get(i).getProvidedName(); } } // Find if there is any fragments selected EventType targetType = null; if (insertIntoDesc != null) { targetType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName()); } // Find if there is any fragment event types: // This is a special case for fragments: select a, b from pattern [a=A -> b=B] // We'd like to maintain 'A' and 'B' EventType in the Map type, and 'a' and 'b' EventBeans in // the event bean for (int i = 0; i < selectionList.size(); i++) { if (!(exprNodes[i] instanceof ExprIdentNode)) { continue; } ExprIdentNode identNode = (ExprIdentNode) exprNodes[i]; String propertyName = identNode.getResolvedPropertyName(); final int streamNum = identNode.getStreamId(); EventType eventTypeStream = typeService.getEventTypes()[streamNum]; if (eventTypeStream instanceof NativeEventType) { continue; // we do not transpose the native type for performance reasons } FragmentEventType fragmentType = eventTypeStream.getFragmentType(propertyName); if ((fragmentType == null) || (fragmentType.isNative())) { continue; // we also ignore native Java classes as fragments for performance reasons } // may need to unwrap the fragment if the target type has this underlying type FragmentEventType targetFragment = null; if (targetType != null) { targetFragment = targetType.getFragmentType(columnNames[i]); } if ((targetType != null) && (fragmentType.getFragmentType().getUnderlyingType() == expressionReturnTypes[i]) && ((targetFragment == null) || (targetFragment != null && targetFragment.isNative()))) { ExprEvaluator evaluatorFragment; // A match was found, we replace the expression final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName); final Class returnType = eventTypeStream.getPropertyType(propertyName); evaluatorFragment = new ExprEvaluator() { public Object evaluate( EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { EventBean streamEvent = eventsPerStream[streamNum]; if (streamEvent == null) { return null; } return getter.get(streamEvent); } public Class getType() { return returnType; } @Override public Map<String, Object> getEventType() { return null; } }; exprEvaluators[i] = evaluatorFragment; } // same for arrays: may need to unwrap the fragment if the target type has this underlying // type else if ((targetType != null) && expressionReturnTypes[i] instanceof Class && (fragmentType.getFragmentType().getUnderlyingType() == ((Class) expressionReturnTypes[i]).getComponentType()) && ((targetFragment == null) || (targetFragment != null && targetFragment.isNative()))) { ExprEvaluator evaluatorFragment; final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName); final Class returnType = JavaClassHelper.getArrayType(eventTypeStream.getPropertyType(propertyName)); evaluatorFragment = new ExprEvaluator() { public Object evaluate( EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { EventBean streamEvent = eventsPerStream[streamNum]; if (streamEvent == null) { return null; } return getter.get(streamEvent); } public Class getType() { return returnType; } @Override public Map<String, Object> getEventType() { return null; } }; exprEvaluators[i] = evaluatorFragment; } else { ExprEvaluator evaluatorFragment; final EventPropertyGetter getter = eventTypeStream.getGetter(propertyName); final Class returnType = eventTypeStream.getFragmentType(propertyName).getFragmentType().getUnderlyingType(); // A match was found, we replace the expression evaluatorFragment = new ExprEvaluator() { public Object evaluate( EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { EventBean streamEvent = eventsPerStream[streamNum]; if (streamEvent == null) { return null; } return getter.getFragment(streamEvent); } public Class getType() { return returnType; } public Map<String, Object> getEventType() { return null; } }; exprEvaluators[i] = evaluatorFragment; if (!fragmentType.isIndexed()) { expressionReturnTypes[i] = fragmentType.getFragmentType(); } else { expressionReturnTypes[i] = new EventType[] {fragmentType.getFragmentType()}; } } } // Find if there is any stream expression (ExprStreamNode) : // This is a special case for stream selection: select a, b from A as a, B as b // We'd like to maintain 'A' and 'B' EventType in the Map type, and 'a' and 'b' EventBeans in // the event bean for (int i = 0; i < selectionList.size(); i++) { if (!(exprEvaluators[i] instanceof ExprStreamUnderlyingNode)) { continue; } ExprStreamUnderlyingNode undNode = (ExprStreamUnderlyingNode) exprEvaluators[i]; final int streamNum = undNode.getStreamId(); final Class returnType = undNode.getExprEvaluator().getType(); EventType eventTypeStream = typeService.getEventTypes()[streamNum]; // A match was found, we replace the expression ExprEvaluator evaluator = new ExprEvaluator() { public Object evaluate( EventBean[] eventsPerStream, boolean isNewData, ExprEvaluatorContext exprEvaluatorContext) { return eventsPerStream[streamNum]; } public Class getType() { return returnType; } public Map<String, Object> getEventType() { return null; } }; exprEvaluators[i] = evaluator; expressionReturnTypes[i] = eventTypeStream; } // Build event type that reflects all selected properties Map<String, Object> selPropertyTypes = new LinkedHashMap<String, Object>(); int count = 0; for (int i = 0; i < exprEvaluators.length; i++) { Object expressionReturnType = expressionReturnTypes[count]; selPropertyTypes.put(columnNames[count], expressionReturnType); count++; } if (!selectedStreams.isEmpty()) { for (SelectClauseStreamCompiledSpec element : namedStreams) { EventType eventTypeStream = typeService.getEventTypes()[element.getStreamNumber()]; selPropertyTypes.put(columnNames[count], eventTypeStream); count++; } if (isUsingWildcard && typeService.getEventTypes().length > 1) { for (int i = 0; i < typeService.getEventTypes().length; i++) { EventType eventTypeStream = typeService.getEventTypes()[i]; selPropertyTypes.put(columnNames[count], eventTypeStream); count++; } } } // Handle stream selection EventType underlyingEventType = null; int underlyingStreamNumber = 0; boolean underlyingIsFragmentEvent = false; EventPropertyGetter underlyingPropertyEventGetter = null; ExprEvaluator underlyingExprEvaluator = null; boolean useMapOutput = EventRepresentationUtil.isMap( annotations, configuration, CreateSchemaDesc.AssignedType.NONE); if (!selectedStreams.isEmpty()) { // Resolve underlying event type in the case of wildcard or non-named stream select. // Determine if the we are considering a tagged event or a stream name. if ((isUsingWildcard) || (!unnamedStreams.isEmpty())) { if (!unnamedStreams.isEmpty()) { if (unnamedStreams.get(0).getStreamSelected() != null) { SelectClauseStreamCompiledSpec streamSpec = unnamedStreams.get(0).getStreamSelected(); // the tag.* syntax for : select tag.* from pattern [tag = A] underlyingStreamNumber = streamSpec.getStreamNumber(); if (streamSpec.isFragmentEvent()) { EventType compositeMap = typeService.getEventTypes()[underlyingStreamNumber]; FragmentEventType fragment = compositeMap.getFragmentType(streamSpec.getStreamName()); underlyingEventType = fragment.getFragmentType(); underlyingIsFragmentEvent = true; } // the property.* syntax for : select property.* from A else if (streamSpec.isProperty()) { String propertyName = streamSpec.getStreamName(); Class propertyType = streamSpec.getPropertyType(); int streamNumber = streamSpec.getStreamNumber(); if (JavaClassHelper.isJavaBuiltinDataType(streamSpec.getPropertyType())) { throw new ExprValidationException( "The property wildcard syntax cannot be used on built-in types as returned by property '" + propertyName + "'"); } // create or get an underlying type for that Class underlyingEventType = eventAdapterService.addBeanType( propertyType.getName(), propertyType, false, false, false); selectExprEventTypeRegistry.add(underlyingEventType); underlyingPropertyEventGetter = typeService.getEventTypes()[streamNumber].getGetter(propertyName); if (underlyingPropertyEventGetter == null) { throw new ExprValidationException( "Unexpected error resolving property getter for property " + propertyName); } } // the stream.* syntax for: select a.* from A as a else { underlyingEventType = typeService.getEventTypes()[underlyingStreamNumber]; } } // handle case where the unnamed stream is a "transpose" function else { ExprNode expression = unnamedStreams.get(0).getExpressionSelectedAsStream().getSelectExpression(); Class returnType = expression.getExprEvaluator().getType(); underlyingEventType = eventAdapterService.addBeanType( returnType.getName(), returnType, false, false, false); selectExprEventTypeRegistry.add(underlyingEventType); underlyingExprEvaluator = expression.getExprEvaluator(); } } else { // no un-named stream selectors, but a wildcard was specified if (typeService.getEventTypes().length == 1) { // not a join, we are using the selected event underlyingEventType = typeService.getEventTypes()[0]; if (underlyingEventType instanceof WrapperEventType) { singleStreamWrapper = true; } } else { // For joins, all results are placed in a map with properties for each stream underlyingEventType = null; } } } } SelectExprContext selectExprContext = new SelectExprContext(exprEvaluators, columnNames, eventAdapterService); if (insertIntoDesc == null) { if (!selectedStreams.isEmpty()) { EventType resultEventType; if (underlyingEventType != null) { resultEventType = eventAdapterService.createAnonymousWrapperType( statementId + "_wrapout_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), underlyingEventType, selPropertyTypes); return new EvalSelectStreamWUnderlying( selectExprContext, resultEventType, namedStreams, isUsingWildcard, unnamedStreams, singleStreamWrapper, underlyingIsFragmentEvent, underlyingStreamNumber, underlyingPropertyEventGetter, underlyingExprEvaluator); } else { resultEventType = eventAdapterService.createAnonymousMapType( statementId + "_mapout_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), selPropertyTypes); return new EvalSelectStreamNoUnderlyingMap( selectExprContext, resultEventType, namedStreams, isUsingWildcard); } } if (isUsingWildcard) { EventType resultEventType = eventAdapterService.createAnonymousWrapperType( statementId + "_wrapoutwild_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), eventType, selPropertyTypes); if (singleStreamWrapper) { return new EvalSelectWildcardSSWrapper(selectExprContext, resultEventType); } if (joinWildcardProcessor == null) { return new EvalSelectWildcard(selectExprContext, resultEventType); } return new EvalSelectWildcardJoin( selectExprContext, resultEventType, joinWildcardProcessor); } EventType resultEventType; if (!useMapOutput) { resultEventType = eventAdapterService.createAnonymousObjectArrayType( statementId + "_result_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), selPropertyTypes); } else { resultEventType = eventAdapterService.createAnonymousMapType( statementId + "_result_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), selPropertyTypes); } if (selectExprContext.getExpressionNodes().length == 0) { return new EvalSelectNoWildcardEmptyProps(selectExprContext, resultEventType); } else { if (!useMapOutput) { return new EvalSelectNoWildcardObjectArray(selectExprContext, resultEventType); } return new EvalSelectNoWildcardMap(selectExprContext, resultEventType); } } EventType vaeInnerEventType = null; boolean singleColumnWrapOrBeanCoercion = false; // Additional single-column coercion for non-wrapped type done by // SelectExprInsertEventBeanFactory boolean isRevisionEvent = false; try { if (!selectedStreams.isEmpty()) { EventType resultEventType; if (underlyingEventType != null) // a single stream was selected via "stream.*" and there is no column name { // recast as a Map-type if (underlyingEventType instanceof MapEventType && targetType instanceof MapEventType) { return new EvalSelectStreamWUnderlyingRecastMap( selectExprContext, selectedStreams.get(0).getStreamSelected().getStreamNumber(), targetType); } // recast as a Object-array-type if (underlyingEventType instanceof ObjectArrayEventType && targetType instanceof ObjectArrayEventType) { return new EvalSelectStreamWUnderlyingRecastObjectArray( selectExprContext, selectedStreams.get(0).getStreamSelected().getStreamNumber(), targetType); } // recast as a Bean-type if (underlyingEventType instanceof BeanEventType && targetType instanceof BeanEventType) { SelectClauseExprCompiledSpec expressionAsStream = selectedStreams.get(0).getExpressionSelectedAsStream(); if (expressionAsStream != null) { return new EvalSelectStreamWUnderlyingRecastBean( selectExprContext, expressionAsStream, underlyingEventType, targetType, exprEvaluators.length); } else { return new EvalInsertBeanRecast( targetType, eventAdapterService, selectedStreams.get(0).getStreamSelected().getStreamNumber(), typeService.getEventTypes()); } } // wrap if no recast possible resultEventType = eventAdapterService.addWrapperType( insertIntoDesc.getEventTypeName(), underlyingEventType, selPropertyTypes, false, true); return new EvalSelectStreamWUnderlying( selectExprContext, resultEventType, namedStreams, isUsingWildcard, unnamedStreams, singleStreamWrapper, underlyingIsFragmentEvent, underlyingStreamNumber, underlyingPropertyEventGetter, underlyingExprEvaluator); } else // there are one or more streams selected with column name such as "stream.* as // columnOne" { EventType existingType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName()); if (existingType instanceof BeanEventType) { String name = selectedStreams.get(0).getStreamSelected().getStreamName(); String alias = selectedStreams.get(0).getStreamSelected().getOptionalName(); String syntaxUsed = name + ".*" + (alias != null ? " as " + alias : ""); String syntaxInstead = name + (alias != null ? " as " + alias : ""); throw new ExprValidationException( "The '" + syntaxUsed + "' syntax is not allowed when inserting into an existing bean event type, use the '" + syntaxInstead + "' syntax instead"); } if (existingType == null || existingType instanceof MapEventType) { resultEventType = eventAdapterService.addNestableMapType( insertIntoDesc.getEventTypeName(), selPropertyTypes, null, false, false, false, false, true); Set<String> propertiesToUnwrap = getEventBeanToObjectProps(selPropertyTypes, resultEventType); if (propertiesToUnwrap.isEmpty()) { return new EvalSelectStreamNoUnderlyingMap( selectExprContext, resultEventType, namedStreams, isUsingWildcard); } else { return new EvalSelectStreamNoUndWEventBeanToObj( selectExprContext, resultEventType, namedStreams, isUsingWildcard, propertiesToUnwrap); } } else { Set<String> propertiesToUnwrap = getEventBeanToObjectProps(selPropertyTypes, existingType); if (propertiesToUnwrap.isEmpty()) { return new EvalSelectStreamNoUnderlyingObjectArray( selectExprContext, existingType, namedStreams, isUsingWildcard); } else { return new EvalSelectStreamNoUndWEventBeanToObjObjArray( selectExprContext, existingType, namedStreams, isUsingWildcard, propertiesToUnwrap); } } } } ValueAddEventProcessor vaeProcessor = valueAddEventService.getValueAddProcessor(insertIntoDesc.getEventTypeName()); EventType resultEventType; if (isUsingWildcard) { if (vaeProcessor != null) { resultEventType = vaeProcessor.getValueAddEventType(); isRevisionEvent = true; vaeProcessor.validateEventType(eventType); } else { EventType existingType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName()); SelectExprProcessor existingTypeProcessor = null; if (existingType != null) { // we may get away with re-casting an existing bean-event-type event to another // bean-event-type if ((existingType instanceof BeanEventType) && (typeService.getEventTypes()[0] instanceof BeanEventType) && (selPropertyTypes.isEmpty())) { return new EvalInsertBeanRecast( existingType, eventAdapterService, 0, typeService.getEventTypes()); } if ((existingType instanceof WrapperEventType) && (typeService.getEventTypes()[0] instanceof BeanEventType) && (exprEvaluators.length == 0)) { WrapperEventType wrapperType = (WrapperEventType) existingType; if (wrapperType.getUnderlyingEventType() instanceof BeanEventType) { return new EvalInsertBeanWrapRecast( wrapperType, eventAdapterService, 0, typeService.getEventTypes()); } } existingTypeProcessor = SelectExprInsertEventBeanFactory.getInsertUnderlyingNonJoin( eventAdapterService, existingType, isUsingWildcard, typeService, exprEvaluators, columnNames, expressionReturnTypes, methodResolutionService.getEngineImportService(), insertIntoDesc, columnNamesAsProvided); } if (existingTypeProcessor != null) { return existingTypeProcessor; } else if (existingType != null && selPropertyTypes.isEmpty() && existingType instanceof MapEventType) { resultEventType = existingType; return new EvalInsertCoercionMap(resultEventType, eventAdapterService); } else if (existingType != null && selPropertyTypes.isEmpty() && existingType instanceof ObjectArrayEventType) { resultEventType = existingType; return new EvalInsertCoercionObjectArray(resultEventType, eventAdapterService); } else if (selPropertyTypes.isEmpty() && eventType instanceof BeanEventType) { BeanEventType beanEventType = (BeanEventType) eventType; resultEventType = eventAdapterService.addBeanTypeByName( insertIntoDesc.getEventTypeName(), beanEventType.getUnderlyingType(), false); } else { resultEventType = eventAdapterService.addWrapperType( insertIntoDesc.getEventTypeName(), eventType, selPropertyTypes, false, true); } } if (singleStreamWrapper) { if (!isRevisionEvent) { return new EvalInsertWildcardSSWrapper(selectExprContext, resultEventType); } else { return new EvalInsertWildcardSSWrapperRevision( selectExprContext, resultEventType, vaeProcessor); } } if (joinWildcardProcessor == null) { if (!isRevisionEvent) { if (resultEventType instanceof WrapperEventType) { return new EvalInsertWildcardWrapper(selectExprContext, resultEventType); } else { return new EvalInsertWildcardBean(selectExprContext, resultEventType); } } else { if (exprEvaluators.length == 0) { return new EvalInsertWildcardRevision( selectExprContext, resultEventType, vaeProcessor); } else { EventType wrappingEventType = eventAdapterService.addWrapperType( insertIntoDesc.getEventTypeName() + "_wrapped", eventType, selPropertyTypes, false, true); return new EvalInsertWildcardRevisionWrapper( selectExprContext, resultEventType, vaeProcessor, wrappingEventType); } } } else { if (!isRevisionEvent) { return new EvalInsertWildcardJoin( selectExprContext, resultEventType, joinWildcardProcessor); } else { return new EvalInsertWildcardJoinRevision( selectExprContext, resultEventType, joinWildcardProcessor, vaeProcessor); } } } // not using wildcard resultEventType = null; if ((columnNames.length == 1) && (insertIntoDesc.getColumnNames().size() == 0)) { EventType existingType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName()); if (existingType != null) { // check if the existing type and new type are compatible Object columnOneType = expressionReturnTypes[0]; if (existingType instanceof WrapperEventType) { WrapperEventType wrapperType = (WrapperEventType) existingType; // Map and Object both supported if (wrapperType.getUnderlyingEventType().getUnderlyingType() == columnOneType) { singleColumnWrapOrBeanCoercion = true; resultEventType = existingType; } } if ((existingType instanceof BeanEventType) && (columnOneType instanceof Class)) { BeanEventType beanType = (BeanEventType) existingType; // Map and Object both supported if (JavaClassHelper.isSubclassOrImplementsInterface( (Class) columnOneType, beanType.getUnderlyingType())) { singleColumnWrapOrBeanCoercion = true; resultEventType = existingType; } } } } if (singleColumnWrapOrBeanCoercion) { if (!isRevisionEvent) { if (resultEventType instanceof WrapperEventType) { WrapperEventType wrapper = (WrapperEventType) resultEventType; if (wrapper.getUnderlyingEventType() instanceof MapEventType) { return new EvalInsertNoWildcardSingleColCoercionMapWrap( selectExprContext, resultEventType); } else if (wrapper.getUnderlyingEventType() instanceof ObjectArrayEventType) { return new EvalInsertNoWildcardSingleColCoercionObjectArrayWrap( selectExprContext, resultEventType); } else if (wrapper.getUnderlyingEventType() instanceof VariantEventType) { VariantEventType variantEventType = (VariantEventType) wrapper.getUnderlyingEventType(); vaeProcessor = valueAddEventService.getValueAddProcessor(variantEventType.getName()); return new EvalInsertNoWildcardSingleColCoercionBeanWrapVariant( selectExprContext, resultEventType, vaeProcessor); } else { return new EvalInsertNoWildcardSingleColCoercionBeanWrap( selectExprContext, resultEventType); } } else { if (resultEventType instanceof BeanEventType) { return new EvalInsertNoWildcardSingleColCoercionBean( selectExprContext, resultEventType); } } } else { if (resultEventType instanceof MapEventType) { return new EvalInsertNoWildcardSingleColCoercionRevisionMap( selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType); } else if (resultEventType instanceof ObjectArrayEventType) { return new EvalInsertNoWildcardSingleColCoercionRevisionObjectArray( selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType); } else if (resultEventType instanceof BeanEventType) { return new EvalInsertNoWildcardSingleColCoercionRevisionBean( selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType); } else { return new EvalInsertNoWildcardSingleColCoercionRevisionBeanWrap( selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType); } } } if (resultEventType == null) { if (vaeProcessor != null) { // Use an anonymous type if the target is not a variant stream if (valueAddEventService.getValueAddProcessor(insertIntoDesc.getEventTypeName()) == null) { resultEventType = eventAdapterService.createAnonymousMapType( statementId + "_vae_" + CollectionUtil.toString(assignedTypeNumberStack, "_"), selPropertyTypes); } else { String statementName = "stmt_" + statementId + "_insert"; resultEventType = eventAdapterService.addNestableMapType( statementName, selPropertyTypes, null, false, false, false, false, true); } } else { EventType existingType = eventAdapterService.getExistsTypeByName(insertIntoDesc.getEventTypeName()); if (existingType == null) { // The type may however be an auto-import or fully-qualified class name Class clazz = null; try { clazz = this.methodResolutionService.resolveClass(insertIntoDesc.getEventTypeName()); } catch (EngineImportException e) { log.debug( "Target stream name '" + insertIntoDesc.getEventTypeName() + "' is not resolved as a class name"); } if (clazz != null) { existingType = eventAdapterService.addBeanType(clazz.getName(), clazz, false, false, false); } } SelectExprProcessor selectExprInsertEventBean = null; if (existingType != null) { selectExprInsertEventBean = SelectExprInsertEventBeanFactory.getInsertUnderlyingNonJoin( eventAdapterService, existingType, isUsingWildcard, typeService, exprEvaluators, columnNames, expressionReturnTypes, methodResolutionService.getEngineImportService(), insertIntoDesc, columnNamesAsProvided); } if (selectExprInsertEventBean != null) { return selectExprInsertEventBean; } else { boolean useMap = EventRepresentationUtil.isMap( annotations, configuration, CreateSchemaDesc.AssignedType.NONE); if (useMap) { resultEventType = eventAdapterService.addNestableMapType( insertIntoDesc.getEventTypeName(), selPropertyTypes, null, false, false, false, false, true); } else { resultEventType = eventAdapterService.addNestableObjectArrayType( insertIntoDesc.getEventTypeName(), selPropertyTypes, null, false, false, false, false, true); } } } } if (vaeProcessor != null) { vaeProcessor.validateEventType(resultEventType); vaeInnerEventType = resultEventType; resultEventType = vaeProcessor.getValueAddEventType(); isRevisionEvent = true; } if (!isRevisionEvent) { if (resultEventType instanceof MapEventType) { return new EvalInsertNoWildcardMap(selectExprContext, resultEventType); } else { return new EvalInsertNoWildcardObjectArray(selectExprContext, resultEventType); } } else { return new EvalInsertNoWildcardRevision( selectExprContext, resultEventType, vaeProcessor, vaeInnerEventType); } } catch (EventAdapterException ex) { log.debug("Exception provided by event adapter: " + ex.getMessage(), ex); throw new ExprValidationException(ex.getMessage(), ex); } }
private void checkInitProperties() { if (numPropertiesUnderlyingType != underlyingEventType.getPropertyDescriptors().length) { updatePropertySet(); } }
public boolean isProperty(String property) { return underlyingEventType.isProperty(property) || underlyingMapType.isProperty(property); }
public EventPropertyGetter getGetter(final String property) { EventPropertyGetter cachedGetter = propertyGetterCache.get(property); if (cachedGetter != null) { return cachedGetter; } if (underlyingMapType.isProperty(property) && (property.indexOf('?') == -1)) { final EventPropertyGetter mapGetter = underlyingMapType.getGetter(property); EventPropertyGetter getter = new EventPropertyGetter() { public Object get(EventBean theEvent) { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; Map map = wrapperEvent.getDecoratingProperties(); return mapGetter.get(eventAdapterService.adapterForTypedMap(map, underlyingMapType)); } public boolean isExistsProperty(EventBean eventBean) { return true; // Property exists as the property is not dynamic (unchecked) } public Object getFragment(EventBean theEvent) { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; Map map = wrapperEvent.getDecoratingProperties(); return mapGetter.getFragment( eventAdapterService.adapterForTypedMap(map, underlyingMapType)); } }; propertyGetterCache.put(property, getter); return getter; } else if (underlyingEventType.isProperty(property)) { EventPropertyGetter getter = new EventPropertyGetter() { public Object get(EventBean theEvent) { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; EventBean wrappedEvent = wrapperEvent.getUnderlyingEvent(); if (wrappedEvent == null) { return null; } EventPropertyGetter underlyingGetter = underlyingEventType.getGetter(property); return underlyingGetter.get(wrappedEvent); } public boolean isExistsProperty(EventBean eventBean) { return true; // Property exists as the property is not dynamic (unchecked) } public Object getFragment(EventBean theEvent) { if (!(theEvent instanceof DecoratingEventBean)) { throw new PropertyAccessException("Mismatched property getter to EventBean type"); } DecoratingEventBean wrapperEvent = (DecoratingEventBean) theEvent; EventBean wrappedEvent = wrapperEvent.getUnderlyingEvent(); if (wrappedEvent == null) { return null; } EventPropertyGetter underlyingGetter = underlyingEventType.getGetter(property); return underlyingGetter.getFragment(wrappedEvent); } }; propertyGetterCache.put(property, getter); return getter; } else { return null; } }
public void testNestedPojo() { Pair<String[], Object[]> pair = getTestDefTwo(); EPServiceProvider epService = getEngineInitialized("NestedObjectArr", pair.getFirst(), pair.getSecond()); String statementText = "select " + "simple, object, nodefmap, map, " + "object.id as a1, nodefmap.key1? as a2, nodefmap.key2? as a3, nodefmap.key3?.key4 as a4, " + "map.objectOne as b1, map.simpleOne as b2, map.nodefmapOne.key2? as b3, map.mapOne.simpleTwo? as b4, " + "map.objectOne.indexed[1] as c1, map.objectOne.nested.nestedValue as c2," + "map.mapOne.simpleTwo as d1, map.mapOne.objectTwo as d2, map.mapOne.nodefmapTwo as d3, " + "map.mapOne.mapTwo as e1, map.mapOne.mapTwo.simpleThree as e2, map.mapOne.mapTwo.objectThree as e3, " + "map.mapOne.objectTwo.array[1].mapped('1ma').value as f1, map.mapOne.mapTwo.objectThree.id as f2" + " from NestedObjectArr"; EPStatement statement = epService.getEPAdministrator().createEPL(statementText); SupportUpdateListener listener = new SupportUpdateListener(); statement.addListener(listener); Object[] testdata = getTestDataTwo(); epService.getEPRuntime().sendEvent(testdata, "NestedObjectArr"); // test all properties exist EventBean received = listener.assertOneGetNewAndReset(); EPAssertionUtil.assertProps( received, "simple,object,nodefmap,map".split(","), new Object[] {"abc", new SupportBean_A("A1"), testdata[2], testdata[3]}); EPAssertionUtil.assertProps( received, "a1,a2,a3,a4".split(","), new Object[] {"A1", "val1", null, null}); EPAssertionUtil.assertProps( received, "b1,b2,b3,b4".split(","), new Object[] {getNestedKey(testdata, 3, "objectOne"), 10, "val2", 300}); EPAssertionUtil.assertProps(received, "c1,c2".split(","), new Object[] {2, "nestedValue"}); EPAssertionUtil.assertProps( received, "d1,d2,d3".split(","), new Object[] { 300, getNestedKey(testdata, 3, "mapOne", "objectTwo"), getNestedKey(testdata, 3, "mapOne", "nodefmapTwo") }); EPAssertionUtil.assertProps( received, "e1,e2,e3".split(","), new Object[] { getNestedKey(testdata, 3, "mapOne", "mapTwo"), 4000L, new SupportBean_B("B1") }); EPAssertionUtil.assertProps(received, "f1,f2".split(","), new Object[] {"1ma0", "B1"}); // assert type info EPStatement stmt = epService.getEPAdministrator().createEPL(("select * from NestedObjectArr")); EventType eventType = stmt.getEventType(); String[] propertiesReceived = eventType.getPropertyNames(); String[] propertiesExpected = new String[] {"simple", "object", "nodefmap", "map"}; EPAssertionUtil.assertEqualsAnyOrder(propertiesReceived, propertiesExpected); assertEquals(String.class, eventType.getPropertyType("simple")); assertEquals(Map.class, eventType.getPropertyType("map")); assertEquals(Map.class, eventType.getPropertyType("nodefmap")); assertEquals(SupportBean_A.class, eventType.getPropertyType("object")); assertNull(eventType.getPropertyType("map.mapOne.simpleOne")); // nested POJO with generic return type listener.reset(); epService .getEPAdministrator() .getConfiguration() .addEventType("MyNested", new String[] {"bean"}, new Object[] {MyNested.class}); EPStatement stmtTwo = epService .getEPAdministrator() .createEPL("select * from MyNested(bean.insides.anyOf(i=>id = 'A'))"); stmtTwo.addListener(listener); epService .getEPRuntime() .sendEvent( new Object[] {new MyNested(Arrays.asList(new MyInside[] {new MyInside("A")}))}, "MyNested"); assertTrue(listener.isInvoked()); }
private void runObjectArrInheritanceAssertion(EPServiceProvider epService) { SupportUpdateListener listeners[] = new SupportUpdateListener[5]; String[] statements = { "select base as vbase, sub1? as v1, sub2? as v2, suba? as va, subb? as vb from RootEvent", // 0 "select base as vbase, sub1 as v1, sub2? as v2, suba? as va, subb? as vb from Sub1Event", // 1 "select base as vbase, sub1? as v1, sub2 as v2, suba? as va, subb? as vb from Sub2Event", // 2 "select base as vbase, sub1 as v1, sub2? as v2, suba as va, subb? as vb from SubAEvent", // 3 "select base as vbase, sub1? as v1, sub2? as v2, suba? as va, subb as vb from SubBEvent" // 4 }; for (int i = 0; i < statements.length; i++) { EPStatement statement = epService.getEPAdministrator().createEPL(statements[i]); listeners[i] = new SupportUpdateListener(); statement.addListener(listeners[i]); } String[] fields = "vbase,v1,v2,va,vb".split(","); EventType type = epService.getEPAdministrator().getConfiguration().getEventType("SubAEvent"); assertEquals("base", type.getPropertyDescriptors()[0].getPropertyName()); assertEquals("sub1", type.getPropertyDescriptors()[1].getPropertyName()); assertEquals("suba", type.getPropertyDescriptors()[2].getPropertyName()); assertEquals(3, type.getPropertyDescriptors().length); type = epService.getEPAdministrator().getConfiguration().getEventType("SubBEvent"); assertEquals("[base, sub1, suba, subb]", Arrays.toString(type.getPropertyNames())); assertEquals(4, type.getPropertyDescriptors().length); type = epService.getEPAdministrator().getConfiguration().getEventType("Sub1Event"); assertEquals("[base, sub1]", Arrays.toString(type.getPropertyNames())); assertEquals(2, type.getPropertyDescriptors().length); type = epService.getEPAdministrator().getConfiguration().getEventType("Sub2Event"); assertEquals("[base, sub2]", Arrays.toString(type.getPropertyNames())); assertEquals(2, type.getPropertyDescriptors().length); epService .getEPRuntime() .sendEvent(new Object[] {"a", "b", "x"}, "SubAEvent"); // base, sub1, suba EPAssertionUtil.assertProps( listeners[0].assertOneGetNewAndReset(), fields, new Object[] {"a", "b", null, "x", null}); assertFalse(listeners[2].isInvoked() || listeners[4].isInvoked()); EPAssertionUtil.assertProps( listeners[1].assertOneGetNewAndReset(), fields, new Object[] {"a", "b", null, "x", null}); EPAssertionUtil.assertProps( listeners[3].assertOneGetNewAndReset(), fields, new Object[] {"a", "b", null, "x", null}); epService.getEPRuntime().sendEvent(new Object[] {"f1", "f2", "f4"}, "SubAEvent"); EPAssertionUtil.assertProps( listeners[0].assertOneGetNewAndReset(), fields, new Object[] {"f1", "f2", null, "f4", null}); assertFalse(listeners[2].isInvoked() || listeners[4].isInvoked()); EPAssertionUtil.assertProps( listeners[1].assertOneGetNewAndReset(), fields, new Object[] {"f1", "f2", null, "f4", null}); EPAssertionUtil.assertProps( listeners[3].assertOneGetNewAndReset(), fields, new Object[] {"f1", "f2", null, "f4", null}); epService.getEPRuntime().sendEvent(new Object[] {"XBASE", "X1", "X2", "XY"}, "SubBEvent"); Object[] values = new Object[] {"XBASE", "X1", null, "X2", "XY"}; EPAssertionUtil.assertProps(listeners[0].assertOneGetNewAndReset(), fields, values); assertFalse(listeners[2].isInvoked()); EPAssertionUtil.assertProps(listeners[1].assertOneGetNewAndReset(), fields, values); EPAssertionUtil.assertProps(listeners[3].assertOneGetNewAndReset(), fields, values); EPAssertionUtil.assertProps(listeners[4].assertOneGetNewAndReset(), fields, values); epService.getEPRuntime().sendEvent(new Object[] {"YBASE", "Y1"}, "Sub1Event"); values = new Object[] {"YBASE", "Y1", null, null, null}; EPAssertionUtil.assertProps(listeners[0].assertOneGetNewAndReset(), fields, values); assertFalse(listeners[2].isInvoked() || listeners[3].isInvoked() || listeners[4].isInvoked()); EPAssertionUtil.assertProps(listeners[1].assertOneGetNewAndReset(), fields, values); epService.getEPRuntime().sendEvent(new Object[] {"YBASE", "Y2"}, "Sub2Event"); values = new Object[] {"YBASE", null, "Y2", null, null}; EPAssertionUtil.assertProps(listeners[0].assertOneGetNewAndReset(), fields, values); assertFalse(listeners[1].isInvoked() || listeners[3].isInvoked() || listeners[4].isInvoked()); EPAssertionUtil.assertProps(listeners[2].assertOneGetNewAndReset(), fields, values); epService.getEPRuntime().sendEvent(new Object[] {"ZBASE"}, "RootEvent"); values = new Object[] {"ZBASE", null, null, null, null}; EPAssertionUtil.assertProps(listeners[0].assertOneGetNewAndReset(), fields, values); assertFalse( listeners[1].isInvoked() || listeners[2].isInvoked() || listeners[3].isInvoked() || listeners[4].isInvoked()); // try property not available try { epService.getEPAdministrator().createEPL("select suba from Sub1Event"); fail(); } catch (EPStatementException ex) { assertEquals( "Error starting statement: Failed to validate select-clause expression 'suba': Property named 'suba' is not valid in any stream (did you mean 'sub1'?) [select suba from Sub1Event]", ex.getMessage()); } // try supertype not exists try { epService .getEPAdministrator() .getConfiguration() .addEventType("Sub1Event", makeMap(""), new String[] {"doodle"}); fail(); } catch (ConfigurationException ex) { assertEquals("Supertype by name 'doodle' could not be found", ex.getMessage()); } }