// Path: src/de/neuland/firefly/EventDistributor.java
// public abstract class EventDistributor<T extends AbstractEvent, L> extends AbstractEventListener<T> {
//     private HashMap<String, Set<L>> registeredListener = new HashMap<>();
// 
//     public EventDistributor(ClusterService clusterService,
//                             TenantService tenantService) {
//         setClusterService(clusterService);
//         setTenantService(tenantService);
//     }
// 
//     public void registerListener(String tenantId, L listener) {
//         hasText(tenantId);
//         notNull(listener);
//         final Set<L> listeners;
//         if (registeredListener.containsKey(tenantId)) {
//             listeners = registeredListener.get(tenantId);
//         } else {
//             listeners = new WeakHashSet();
//             registeredListener.put(tenantId, listeners);
//         }
//         listeners.add(listener);
//     }
// 
//     public void unregisterListener(L listener) {
//         for (Set<L> listeners : registeredListener.values()) {
//             listeners.remove(listener);
//         }
//     }
// 
//     public boolean isListenerRegistered(L listener) {
//         for (Set<L> listeners : registeredListener.values()) {
//             if (listeners.contains(listener)) {
//                 return true;
//             }
//         }
//         return false;
//     }
// 
//     protected boolean hasListenersForTenant(String tenantId) {
//         return registeredListener.containsKey(tenantId);
//     }
// 
//     protected Set<L> getListenersForTenant(String tenantId) {
//         return registeredListener.get(tenantId);
//     }
// 
//     // overridden to neutralize @Required annotation of method id super class
//     @Override
//     public void setClusterService(ClusterService clusterService) {
//         super.setClusterService(clusterService);
//     }
// 
//     // overridden to neutralize @Required annotation of method id super class
//     @Override
//     public void setTenantService(TenantService tenantService) {
//         super.setTenantService(tenantService);
//     }
// }
// 
// Path: src/de/neuland/firefly/extensionfinder/FireflyExtensionRepository.java
// @Repository
// @Scope("prototype")
// public class FireflyExtensionRepository {
//     @Autowired ModelService modelService;
//     @Autowired FlexibleSearchService searchService;
// 
//     public FireflyExtensionModel findByName(String name) throws FireflyExtensionNotFoundException, FireflyNotInstalledException {
//         final FlexibleSearchQuery query = new FlexibleSearchQuery(
//                         "SELECT {" + FireflyExtensionModel.PK + "} " +
//                         "FROM {" + FireflyExtensionModel._TYPECODE + "} " +
//                         "WHERE {" + FireflyExtensionModel.NAME + "} = ?name");
//         query.addQueryParameter("name", name);
//         try {
//             return searchService.searchUnique(query);
//         } catch (FlexibleSearchException e) {
//             throw new FireflyNotInstalledException(e);
//         } catch (ModelNotFoundException e) {
//             throw new FireflyExtensionNotFoundException(name);
//         }
//     }
// 
//     public FireflyExtensionModel create(String name) {
//         Assert.hasText(name);
//         FireflyExtensionModel result = new FireflyExtensionModel();
//         result.setName(name);
//         result.setStates(new ArrayList<FireflyExtensionStateModel>());
//         return result;
//     }
// 
//     public void save(FireflyExtensionModel model) {
//         modelService.save(model);
//     }
// 
//     public static class FireflyNotInstalledException extends RuntimeException {
//         public FireflyNotInstalledException(Exception e) {
//             super(e);
//         }
//     }
// 
//     public static class FireflyExtensionNotFoundException extends Exception {
//         private String name;
// 
//         public FireflyExtensionNotFoundException(String name) {
//             super("No " + FireflyExtensionModel._TYPECODE + " found for name=" + name);
//             this.name = name;
//         }
// 
//         public String getName() {
//             return name;
//         }
//     }
// }


import de.hybris.platform.servicelayer.cluster.ClusterService;
import de.hybris.platform.servicelayer.tenant.TenantService;
import de.neuland.firefly.EventDistributor;
import de.neuland.firefly.extensionfinder.FireflyExtensionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
package de.neuland.firefly.changes;



@Component
@Scope("singleton")
public class ChangeExecutedEventListener extends EventDistributor<ChangeExecutedEvent, Change> {

    @Autowired
    public ChangeExecutedEventListener(ClusterService clusterService,
                                       TenantService tenantService,
                                       ApplicationContext applicationContext) {
        super(clusterService, tenantService);

        super.setApplicationContext(applicationContext);
    }

    @Override protected void onEvent(ChangeExecutedEvent event) {
        if (!hasListenersForTenant(event.getTenantId())) {
            return;
        }

        try {
            for (Change change : getListenersForTenant(event.getTenantId())) {
                if (change.equals(event.getChange())) {
                    change.onExecution(event.getMigration());
                }
            }
// Path: src/de/neuland/firefly/EventDistributor.java
// public abstract class EventDistributor<T extends AbstractEvent, L> extends AbstractEventListener<T> {
//     private HashMap<String, Set<L>> registeredListener = new HashMap<>();
// 
//     public EventDistributor(ClusterService clusterService,
//                             TenantService tenantService) {
//         setClusterService(clusterService);
//         setTenantService(tenantService);
//     }
// 
//     public void registerListener(String tenantId, L listener) {
//         hasText(tenantId);
//         notNull(listener);
//         final Set<L> listeners;
//         if (registeredListener.containsKey(tenantId)) {
//             listeners = registeredListener.get(tenantId);
//         } else {
//             listeners = new WeakHashSet();
//             registeredListener.put(tenantId, listeners);
//         }
//         listeners.add(listener);
//     }
// 
//     public void unregisterListener(L listener) {
//         for (Set<L> listeners : registeredListener.values()) {
//             listeners.remove(listener);
//         }
//     }
// 
//     public boolean isListenerRegistered(L listener) {
//         for (Set<L> listeners : registeredListener.values()) {
//             if (listeners.contains(listener)) {
//                 return true;
//             }
//         }
//         return false;
//     }
// 
//     protected boolean hasListenersForTenant(String tenantId) {
//         return registeredListener.containsKey(tenantId);
//     }
// 
//     protected Set<L> getListenersForTenant(String tenantId) {
//         return registeredListener.get(tenantId);
//     }
// 
//     // overridden to neutralize @Required annotation of method id super class
//     @Override
//     public void setClusterService(ClusterService clusterService) {
//         super.setClusterService(clusterService);
//     }
// 
//     // overridden to neutralize @Required annotation of method id super class
//     @Override
//     public void setTenantService(TenantService tenantService) {
//         super.setTenantService(tenantService);
//     }
// }
// 
// Path: src/de/neuland/firefly/extensionfinder/FireflyExtensionRepository.java
// @Repository
// @Scope("prototype")
// public class FireflyExtensionRepository {
//     @Autowired ModelService modelService;
//     @Autowired FlexibleSearchService searchService;
// 
//     public FireflyExtensionModel findByName(String name) throws FireflyExtensionNotFoundException, FireflyNotInstalledException {
//         final FlexibleSearchQuery query = new FlexibleSearchQuery(
//                         "SELECT {" + FireflyExtensionModel.PK + "} " +
//                         "FROM {" + FireflyExtensionModel._TYPECODE + "} " +
//                         "WHERE {" + FireflyExtensionModel.NAME + "} = ?name");
//         query.addQueryParameter("name", name);
//         try {
//             return searchService.searchUnique(query);
//         } catch (FlexibleSearchException e) {
//             throw new FireflyNotInstalledException(e);
//         } catch (ModelNotFoundException e) {
//             throw new FireflyExtensionNotFoundException(name);
//         }
//     }
// 
//     public FireflyExtensionModel create(String name) {
//         Assert.hasText(name);
//         FireflyExtensionModel result = new FireflyExtensionModel();
//         result.setName(name);
//         result.setStates(new ArrayList<FireflyExtensionStateModel>());
//         return result;
//     }
// 
//     public void save(FireflyExtensionModel model) {
//         modelService.save(model);
//     }
// 
//     public static class FireflyNotInstalledException extends RuntimeException {
//         public FireflyNotInstalledException(Exception e) {
//             super(e);
//         }
//     }
// 
//     public static class FireflyExtensionNotFoundException extends Exception {
//         private String name;
// 
//         public FireflyExtensionNotFoundException(String name) {
//             super("No " + FireflyExtensionModel._TYPECODE + " found for name=" + name);
//             this.name = name;
//         }
// 
//         public String getName() {
//             return name;
//         }
//     }
// }


// Path: src/de/neuland/firefly/changes/ChangeExecutedEventListener.java
import de.hybris.platform.servicelayer.cluster.ClusterService;
import de.hybris.platform.servicelayer.tenant.TenantService;
import de.neuland.firefly.EventDistributor;
import de.neuland.firefly.extensionfinder.FireflyExtensionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

package de.neuland.firefly.changes;



@Component
@Scope("singleton")
public class ChangeExecutedEventListener extends EventDistributor<ChangeExecutedEvent, Change> {

    @Autowired
    public ChangeExecutedEventListener(ClusterService clusterService,
                                       TenantService tenantService,
                                       ApplicationContext applicationContext) {
        super(clusterService, tenantService);

        super.setApplicationContext(applicationContext);
    }

    @Override protected void onEvent(ChangeExecutedEvent event) {
        if (!hasListenersForTenant(event.getTenantId())) {
            return;
        }

        try {
            for (Change change : getListenersForTenant(event.getTenantId())) {
                if (change.equals(event.getChange())) {
                    change.onExecution(event.getMigration());
                }
            }
        } catch (FireflyExtensionRepository.FireflyExtensionNotFoundException e) {