/* * Copyright 2014-2016 CyberVision, Inc. * * 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 org.kaaproject.kaa.server.control.service.sdk.event; import static java.util.stream.Collectors.joining; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.kaaproject.kaa.common.dto.event.ApplicationEventAction; import org.kaaproject.kaa.common.dto.event.ApplicationEventMapDto; import org.kaaproject.kaa.server.control.service.sdk.SdkGenerator; import org.kaaproject.kaa.server.control.service.sdk.compress.TarEntryData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CppEventSourcesGenerator { private static final Logger LOG = LoggerFactory.getLogger(CppEventSourcesGenerator.class); private static final String EVENT_FAMILY_HPP_TEMPLATE = "sdk/cpp/event/EventFamily.hpp.template"; private static final String EVENT_FAMILY_ADD_SUPPORTED_FQN_TEMPLATE = "sdk/cpp/event/addSupportedEventClassFqns.template"; private static final String EVENT_FAMILY_ON_GENERIC_EVENT_TEMPLATE = "sdk/cpp/event/eventFamilyOnGenericEvent.template"; private static final String EVENT_FAMILY_NOTIFY_LISTENER_TEMPLATE = "sdk/cpp/event/eventFamilyNotifyListener.template"; private static final String EVENT_FAMILY_SEND_EVENT_METHODS_TEMPLATE = "sdk/cpp/event/eventFamilySendEventMethods.template"; private static final String EVENT_FAMILY_LISTENER_METHOD_TEMPLATE = "sdk/cpp/event/eventFamilyListenerMethod.template"; private static final String EVENT_FAMILY_FACTORY_HPP_TEMPLATE = "sdk/cpp/event/EventFamilyFactory.hpp.template"; private static final String EVENT_FAMILY_INCLUDE_HEADERS_TEMPLATE = "sdk/cpp/event/includeEventFamilyHeaders.template"; private static final String EVENT_FAMILY_FACTORY_ADD_EVENT_FAMILY_TEMPLATE = "sdk/cpp/event/eventFamilyFactoryAddConcreteEventFamily.template"; private static final String EVENT_FAMILY_FACTORY_GET_EVENT_FAMILY_TEMPLATE = "sdk/cpp/event/eventFamilyFactoryGetConcreteEventFamily.template"; private static final String AVRO_STRUCT_GENERATOR_TEMPLATE = "sdk/cpp/event/AvroStructGenerator.cmake.template"; private static final String EVENT_FAMILY_FACTORY_SET_CONCRETE_EVENT_FAMILY_NAMES_TEMPLATE = "sdk/cpp/event/eventFamilyFactorySetEventFamilyClassNames.template"; private static final String EVENT_FAMILY_CLASS_NAME_VAR = "\\$\\{event_family_class_name\\}"; private static final String EVENT_FAMILY_LISTENER_METHODS_VAR = "\\$\\{event_family_listener_methods\\}"; private static final String ADD_SUPPORTED_EVENT_CLASS_FQNS_VAR = "\\$\\{add_supported_event_class_fqns\\}"; private static final String EVENT_FAMILY_LISTENERS_ON_GENERIC_EVENT_VAR = "\\$\\{event_family_listeners_on_generic_event\\}"; private static final String EVENT_FAMILY_LISTENERS_NOTIFY_LISTENER_VAR = "\\$\\{event_family_listeners_notify_listener\\}"; private static final String EVENT_FAMILY_SEND_EVENT_METHODS_VAR = "\\$\\{event_family_send_event_methods\\}"; private static final String EVENT_CLASS_FQN_VAR = "\\$\\{event_class_fqn\\}"; private static final String EVENT_CLASS_NAME_VAR = "\\$\\{event_class_name\\}"; private static final String INCLUDE_EVENT_FAMILY_HEADERS_VAR = "\\$\\{include_event_family_headers\\}"; private static final String EVENT_FAMILY_FACTORY_GET_CONCRETE_EVENT_FAMILY_VAR = "\\$\\{event_family_factory_get_concrete_event_family\\}"; private static final String EVENT_FAMILY_FACTORY_SET_CONCRETE_EVENT_FAMILY_NAMES_VAR = "\\$\\{event_family_factory_set_concrete_event_family_names\\}"; private static final String EVENT_FAMILY_FACTORY_ADD_CONCRETE_EVENT_FAMILY_VAR = "\\$\\{event_family_factory_add_concrete_event_family\\}"; private static final String EVENT_FAMILY_CLASS_LIST_VAR = "\\[event_family_class_list\\]"; private static final String EVENT_FAMILY_FACTORY_PATH = "kaa/event/gen/EventFamilyFactory.hpp"; private static final String EVENT_FAMILY_PATH_TEMPLATE = "kaa/event/gen/${event_family_class_name}.hpp"; private static final String EVENT_FAMILY_SCHEMA_PATH_TEMPLATE = "avro/event/${event_family_class_name}.avsc"; private static final String AVRO_STRUCT_GENERATOR = "Modules/AvroStructGenerator.cmake"; private static final Pattern CLASS_NAME_PATTERN = Pattern.compile(".*?([^.]+)$"); private static String eventFamilyHpp; private static String eventFamilyAddSupportedFqn; private static String eventFamilyOnGenericEvent; private static String eventFamilyNotifyListener; private static String eventFamilySendEventMethod; private static String eventFamilyListenerMethod; private static String eventFamilyFactoryHpp; private static String eventFamilyIncludeHeaders; private static String eventFamilyFactoryGetEventFamily; private static String eventFamilyFactorySetEventFamilyNames; private static String eventFamilyFactoryAddEventFamily; private static String avrogen; static { try { eventFamilyHpp = SdkGenerator.readResource(EVENT_FAMILY_HPP_TEMPLATE); eventFamilyAddSupportedFqn = SdkGenerator .readResource(EVENT_FAMILY_ADD_SUPPORTED_FQN_TEMPLATE); eventFamilyOnGenericEvent = SdkGenerator.readResource(EVENT_FAMILY_ON_GENERIC_EVENT_TEMPLATE); eventFamilyNotifyListener = SdkGenerator.readResource(EVENT_FAMILY_NOTIFY_LISTENER_TEMPLATE); eventFamilySendEventMethod = SdkGenerator .readResource(EVENT_FAMILY_SEND_EVENT_METHODS_TEMPLATE); eventFamilyListenerMethod = SdkGenerator.readResource(EVENT_FAMILY_LISTENER_METHOD_TEMPLATE); eventFamilyFactoryHpp = SdkGenerator.readResource(EVENT_FAMILY_FACTORY_HPP_TEMPLATE); eventFamilyIncludeHeaders = SdkGenerator.readResource(EVENT_FAMILY_INCLUDE_HEADERS_TEMPLATE); eventFamilyFactoryGetEventFamily = SdkGenerator .readResource(EVENT_FAMILY_FACTORY_GET_EVENT_FAMILY_TEMPLATE); eventFamilyFactorySetEventFamilyNames = SdkGenerator .readResource(EVENT_FAMILY_FACTORY_SET_CONCRETE_EVENT_FAMILY_NAMES_TEMPLATE); eventFamilyFactoryAddEventFamily = SdkGenerator .readResource(EVENT_FAMILY_FACTORY_ADD_EVENT_FAMILY_TEMPLATE); avrogen = SdkGenerator.readResource(AVRO_STRUCT_GENERATOR_TEMPLATE); } catch (IOException ex) { LOG.error("Unable to initialize CppEventSourcesGenerator", ex); } } private CppEventSourcesGenerator() { } /** * Create new zip entry data for the event family metadata. * * @param eventFamilies the event family metadata * @return a new zip entry data */ public static List<TarEntryData> generateEventSources(List<EventFamilyMetadata> eventFamilies) { List<TarEntryData> eventSources = new ArrayList<>(); String includeEventFamilyHeaders = ""; String factoryGetEventFamilies = ""; String factorySetEventFamilyNames = ""; String factoryAddEventFamilies = ""; String eventFamilyClassList = ""; for (EventFamilyMetadata efm : eventFamilies) { includeEventFamilyHeaders += eventFamilyIncludeHeaders .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) + "\n"; factoryGetEventFamilies += eventFamilyFactoryGetEventFamily .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) + "\n"; factoryAddEventFamilies += eventFamilyFactoryAddEventFamily .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) + "\n"; if (eventFamilyClassList.length() > 0) { eventFamilyClassList += " "; } eventFamilyClassList += efm.getEcfClassName(); String supportedFqnsList = ""; String eventFamilyListenersOnGenericEvent = ""; String eventFamilyListenersNotifyListener = ""; String eventFamilySendEventMethods = ""; String eventFamilyListenerMethods = ""; for (ApplicationEventMapDto eventMap : efm.getEventMaps()) { Matcher matcher = CLASS_NAME_PATTERN.matcher(eventMap.getFqn()); String eventClassName = (matcher.find()) ? matcher.group(1) : ""; if (eventMap.getAction() == ApplicationEventAction.SINK || eventMap.getAction() == ApplicationEventAction.BOTH) { if (supportedFqnsList.length() > 0) { supportedFqnsList += ","; } supportedFqnsList += "\"" + eventMap.getFqn() + "\""; if (eventFamilyListenersOnGenericEvent.length() > 0) { eventFamilyListenersOnGenericEvent += "else "; } if (eventFamilyListenersNotifyListener.length() > 0) { eventFamilyListenersNotifyListener += "else "; } eventFamilyListenersOnGenericEvent += eventFamilyOnGenericEvent .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(EVENT_CLASS_FQN_VAR, eventMap.getFqn()) .replaceAll(EVENT_CLASS_NAME_VAR, eventClassName) + "\n"; eventFamilyListenersNotifyListener += eventFamilyNotifyListener .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(EVENT_CLASS_FQN_VAR, eventMap.getFqn()) .replaceAll(EVENT_CLASS_NAME_VAR, eventClassName) + "\n"; eventFamilyListenerMethods += eventFamilyListenerMethod .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(EVENT_CLASS_NAME_VAR, eventClassName) + "\n"; } if (eventMap.getAction() == ApplicationEventAction.SOURCE || eventMap.getAction() == ApplicationEventAction.BOTH) { eventFamilySendEventMethods += eventFamilySendEventMethod .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(EVENT_CLASS_FQN_VAR, eventMap.getFqn()) .replaceAll(EVENT_CLASS_NAME_VAR, eventClassName) + "\n"; } } String addSupportedEventClassFqns = eventFamilyAddSupportedFqn .replaceAll(EVENT_CLASS_FQN_VAR, supportedFqnsList); factorySetEventFamilyNames += eventFamilyFactorySetEventFamilyNames .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(ADD_SUPPORTED_EVENT_CLASS_FQNS_VAR, addSupportedEventClassFqns) + "\n"; String eventFamilySource = eventFamilyHpp .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()) .replaceAll(ADD_SUPPORTED_EVENT_CLASS_FQNS_VAR, addSupportedEventClassFqns) .replaceAll(EVENT_FAMILY_LISTENERS_ON_GENERIC_EVENT_VAR, eventFamilyListenersOnGenericEvent) .replaceAll(EVENT_FAMILY_LISTENERS_NOTIFY_LISTENER_VAR, eventFamilyListenersNotifyListener) .replaceAll(EVENT_FAMILY_SEND_EVENT_METHODS_VAR, eventFamilySendEventMethods) .replaceAll(EVENT_FAMILY_LISTENER_METHODS_VAR, eventFamilyListenerMethods); String eventFamilyPath = EVENT_FAMILY_PATH_TEMPLATE .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()); TarArchiveEntry entry = new TarArchiveEntry(eventFamilyPath); byte[] data = eventFamilySource.getBytes(); entry.setSize(data.length); TarEntryData tarEntry = new TarEntryData(entry, data); eventSources.add(tarEntry); String eventCtlSchemas = "[" + efm.getRawCtlsSchemas().stream().collect(joining(",")) + "]"; String eventFamilySchemaPath = EVENT_FAMILY_SCHEMA_PATH_TEMPLATE .replaceAll(EVENT_FAMILY_CLASS_NAME_VAR, efm.getEcfClassName()); entry = new TarArchiveEntry(eventFamilySchemaPath); data = eventCtlSchemas.getBytes(); entry.setSize(data.length); tarEntry = new TarEntryData(entry, data); eventSources.add(tarEntry); } String eventFamilyFactorySource = eventFamilyFactoryHpp .replaceAll(INCLUDE_EVENT_FAMILY_HEADERS_VAR, includeEventFamilyHeaders) .replaceAll(EVENT_FAMILY_FACTORY_GET_CONCRETE_EVENT_FAMILY_VAR, factoryGetEventFamilies) .replaceAll(EVENT_FAMILY_FACTORY_ADD_CONCRETE_EVENT_FAMILY_VAR, factoryAddEventFamilies) .replaceAll(EVENT_FAMILY_FACTORY_SET_CONCRETE_EVENT_FAMILY_NAMES_VAR, factorySetEventFamilyNames); TarArchiveEntry entry = new TarArchiveEntry(EVENT_FAMILY_FACTORY_PATH); byte[] data = eventFamilyFactorySource.getBytes(); entry.setSize(data.length); TarEntryData tarEntry = new TarEntryData(entry, data); eventSources.add(tarEntry); String avrogenSource = avrogen.replaceAll(EVENT_FAMILY_CLASS_LIST_VAR, eventFamilyClassList); entry = new TarArchiveEntry(AVRO_STRUCT_GENERATOR); data = avrogenSource.getBytes(); entry.setSize(data.length); tarEntry = new TarEntryData(entry, data); eventSources.add(tarEntry); return eventSources; } }