/******************************************************************************* * Copyright (c) 2008 Olivier Moises * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Olivier Moises- initial API and implementation *******************************************************************************/ package org.eclipse.wazaabi.engine.edp.adapters; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.wazaabi.engine.edp.Registry; import org.eclipse.wazaabi.engine.edp.coderesolution.DeferredAdapter; import org.eclipse.wazaabi.engine.edp.coderesolution.ExecutableAdapter; import org.eclipse.wazaabi.engine.edp.exceptions.OperationAborted; import org.eclipse.wazaabi.engine.edp.locationpaths.IPointersEvaluator; import org.eclipse.wazaabi.mm.edp.EventDispatcher; import org.eclipse.wazaabi.mm.edp.events.Event; import org.eclipse.wazaabi.mm.edp.handlers.Condition; import org.eclipse.wazaabi.mm.edp.handlers.EDPHandlersPackage; import org.eclipse.wazaabi.mm.edp.handlers.EventHandler; import org.eclipse.wazaabi.mm.edp.handlers.Executable; import org.eclipse.wazaabi.mm.edp.handlers.impl.ConditionImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EventHandlerAdapter extends ActionAdapterImpl implements SequenceAdapter { private final Logger logger = LoggerFactory .getLogger(EventHandlerAdapter.class); private SequenceAdapterImpl innerSequenceAdapter = new SequenceAdapterImpl() { @Override public void setTarget(Notifier newTarget) { Notifier oldTarget = getTarget(); super.setTarget(newTarget); if (newTarget != null && newTarget.equals(oldTarget) && getEventDispatcherAdapter() != null) updateCodeLocatorBaseUris(getEventDispatcherAdapter() .getCodeLocatorBaseUri()); } @Override protected ExecutableAdapter createExecutableAdapterFor( Executable executable) { ExecutableAdapter adapter = (ExecutableAdapter) getRegistry() .createAdapter(EventHandlerAdapter.this, executable, getRegistry(), ExecutableAdapter.class); if (adapter instanceof DeferredAdapter) ((DeferredAdapter) adapter) .setCodeLocatorBaseUri(getCodeLocatorBaseUri()); return adapter; } @Override protected EventDispatcherAdapter getEventDispatcherAdapter() { return EventHandlerAdapter.this.getEventDispatcherAdapter(); } }; protected void eventAdded(Event event) { } protected void eventRemoved(Event event) { } protected void eventDispatcherAdapterAttached( EventDispatcherAdapter eventDispatcherAdapter) { } protected void eventDispatcherAdapterDetached( EventDispatcherAdapter eventDispatcherAdapter) { } private EventDispatcherAdapter eventDispatcherAdapter = null; private List<ConditionAdapter> conditionAdapters = new ArrayList<ConditionAdapter>(); public EventDispatcherAdapter getEventDispatcherAdapter() { return eventDispatcherAdapter; } protected void setEventDispatcherAdapter( EventDispatcherAdapter eventDispatcherAdapter) { if (getEventDispatcherAdapter() != null) eventDispatcherAdapterDetached(getEventDispatcherAdapter()); this.eventDispatcherAdapter = eventDispatcherAdapter; if (eventDispatcherAdapter != null) { eventDispatcherAdapterAttached(eventDispatcherAdapter); String newPathPrefix = eventDispatcherAdapter .getCodeLocatorBaseUri(); innerSequenceAdapter.updateCodeLocatorBaseUris(newPathPrefix); setCodeLocatorBaseUri(newPathPrefix); } else { innerSequenceAdapter.updateCodeLocatorBaseUris(null); setCodeLocatorBaseUri(null); } super.registerMethods(); } public void notifyChanged(Notification notification) { switch (notification.getFeatureID(EventHandler.class)) { case EDPHandlersPackage.EVENT_HANDLER__EVENTS: switch (notification.getEventType()) { case Notification.ADD: adaptEvent((Event) notification.getNewValue()); break; case Notification.ADD_MANY: @SuppressWarnings("unchecked") Collection<Event> addedEvents = (Collection<Event>) notification .getNewValue(); for (Event event : addedEvents) adaptEvent(event); break; case Notification.REMOVE: unadaptEvent((Event) notification.getOldValue()); break; case Notification.REMOVE_MANY: @SuppressWarnings("unchecked") Collection<Event> removedEvents = (Collection<Event>) notification .getOldValue(); for (Event event : removedEvents) unadaptEvent(event); break; } return; case EDPHandlersPackage.EVENT_HANDLER__CONDITIONS: switch (notification.getEventType()) { case Notification.ADD: adaptCondition((Condition) notification.getNewValue()); break; case Notification.ADD_MANY: @SuppressWarnings("unchecked") Collection<ConditionImpl> addedConditions = (Collection<ConditionImpl>) notification .getNewValue(); for (ConditionImpl condition : addedConditions) adaptCondition(condition); break; case Notification.REMOVE: unadaptCondition((Condition) notification.getOldValue()); break; case Notification.REMOVE_MANY: @SuppressWarnings("unchecked") Collection<ConditionImpl> removedConditions = (Collection<ConditionImpl>) notification .getOldValue(); for (ConditionImpl condition : removedConditions) unadaptCondition(condition); break; case Notification.SET: unadaptCondition((Condition) notification.getOldValue()); adaptCondition((Condition) notification.getNewValue()); } } innerSequenceAdapter.notifyChanged(notification); super.notifyChanged(notification); } @Override public void setTarget(Notifier newTarget) { innerSequenceAdapter.setTarget(newTarget); if (newTarget == getTarget()) return; if (getTarget() != null) { for (Event event : ((EventHandler) getTarget()).getEvents()) { unadaptEvent(event); } for (Condition condition : ((EventHandler) getTarget()) .getConditions()) { unadaptCondition(condition); } } super.setTarget(newTarget); if (newTarget != null) { for (Event event : ((EventHandler) getTarget()).getEvents()) { adaptEvent(event); } for (Condition condition : ((EventHandler) getTarget()) .getConditions()) { adaptCondition(condition); } } } protected void adaptEvent(Event event) { EventAdapter adapter = createEventAdapterFor(event); if (adapter != null) { adapter.setEventHandlerAdapter(this); event.eAdapters().add(adapter); } eventAdded(event); } protected void unadaptEvent(Event event) { EventAdapter toRemove = null; for (Adapter adapter : event.eAdapters()) if (adapter instanceof EventAdapter && ((EventAdapter) adapter).getEventHandlerAdapter() == this) { toRemove = (EventAdapter) adapter; break; } if (toRemove != null) { event.eAdapters().remove(toRemove); toRemove.setEventHandlerAdapter(null); } eventRemoved(event); } protected EventAdapter createEventAdapterFor(Event event) { if (getEventDispatcherAdapter() != null) return (EventAdapter) getRegistry().createAdapter(this, event, null, EventAdapter.class); else logger.error("EventDispatcherAdapter not available"); //$NON-NLS-1$ return null; } protected void adaptCondition(Condition condition) { ConditionAdapter conditionAdapter = (ConditionAdapter) createConditionAdapterFor(condition); if (conditionAdapter != null) { condition.eAdapters().add(conditionAdapter); getConditionAdapters().add(conditionAdapter); } } private void unadaptCondition(Condition condition) { ConditionAdapter toRemove = null; for (Adapter adapter : condition.eAdapters()) if (adapter instanceof ConditionAdapter && getConditionAdapters().contains( ((ConditionAdapter) adapter))) { toRemove = (ConditionAdapter) adapter; break; } if (toRemove != null) { condition.eAdapters().remove(toRemove); getConditionAdapters().remove(toRemove); } } protected ConditionAdapter createConditionAdapterFor(Condition condition) { ExecutableAdapter adapter = null; if (getEventDispatcherAdapter() != null) { adapter = (ExecutableAdapter) getRegistry().createAdapter(this, condition, getRegistry(), ExecutableAdapter.class); if (adapter instanceof ConditionAdapter) { ((ConditionAdapter) adapter) .setCodeLocatorBaseUri(getCodeLocatorBaseUri()); return (ConditionAdapter) adapter; } } else logger.error("EventDispatcherAdapter not available"); //$NON-NLS-1$ return null; } public List<ConditionAdapter> getConditionAdapters() { return conditionAdapters; } public void trigger(Event event) throws OperationAborted { EventDispatcher dispatcher = (EventDispatcher) ((EventHandler) getTarget()) .eContainer(); for (ConditionAdapter condition : getConditionAdapters()) { boolean canExecute = false; try { canExecute = condition.canExecute(dispatcher, (EventHandler) getTarget(), event); } catch (RuntimeException e) { throw (OperationAborted) e.getCause(); } if (!canExecute) { return; } } if (((EventHandler) getTarget()).getExecutables().isEmpty()) super.trigger(dispatcher, (EventHandler) getTarget(), event); else innerSequenceAdapter.trigger(dispatcher, (EventHandler) getTarget(), event); } public IPointersEvaluator getPointersEvaluator() { if (getEventDispatcherAdapter() != null) return getEventDispatcherAdapter().getPointersEvaluator(); else logger.error("EventDispatcherAdapter not available"); //$NON-NLS-1$ return null; } public List<ExecutableAdapter> getExecutableAdapters() { return innerSequenceAdapter.getExecutableAdapters(); } @Override protected void registerMethods() { if (getEventDispatcherAdapter() != null) super.registerMethods(); else logger.error("EventDispatcherAdapter not available"); //$NON-NLS-1$ } @Override public Registry getRegistry() { return getEventDispatcherAdapter().getRegistry(); } }