001    package de.deepamehta.core.impl;
002    
003    import de.deepamehta.core.Association;
004    import de.deepamehta.core.AssociationType;
005    import de.deepamehta.core.Topic;
006    import de.deepamehta.core.TopicType;
007    import de.deepamehta.core.model.AssociationModel;
008    import de.deepamehta.core.model.TopicModel;
009    import de.deepamehta.core.service.ClientState;
010    import de.deepamehta.core.service.Directives;
011    import de.deepamehta.core.service.Listener;
012    import de.deepamehta.core.service.event.*;
013    
014    // ### TODO: hide Jersey internals. Move to JAX-RS 2.0.
015    import com.sun.jersey.spi.container.ContainerRequest;
016    import com.sun.jersey.spi.container.ContainerResponse;
017    
018    import javax.servlet.http.HttpServletRequest;
019    
020    import java.util.HashMap;
021    import java.util.Map;
022    
023    
024    
025    /**
026     * Events fired by the DeepaMehta core service.
027     * Plugins can listen to these events by implementing the respective listener interfaces.
028     *
029     * @see de.deepamehta.core.service.event
030     */
031    enum CoreEvent {
032    
033        PRE_CREATE_TOPIC(PreCreateTopicListener.class) {
034            @Override
035            void deliver(Listener listener, Object... params) {
036                ((PreCreateTopicListener) listener).preCreateTopic(
037                    (TopicModel) params[0], (ClientState) params[1]
038                );
039            }
040        },
041        PRE_CREATE_ASSOCIATION(PreCreateAssociationListener.class) {
042            @Override
043            void deliver(Listener listener, Object... params) {
044                ((PreCreateAssociationListener) listener).preCreateAssociation(
045                    (AssociationModel) params[0], (ClientState) params[1]
046                );
047            }
048        },
049    
050        POST_CREATE_TOPIC(PostCreateTopicListener.class) {
051            @Override
052            void deliver(Listener listener, Object... params) {
053                ((PostCreateTopicListener) listener).postCreateTopic(
054                    (Topic) params[0], (ClientState) params[1], (Directives) params[2]
055                );
056            }
057        },
058        POST_CREATE_ASSOCIATION(PostCreateAssociationListener.class) {
059            @Override
060            void deliver(Listener listener, Object... params) {
061                ((PostCreateAssociationListener) listener).postCreateAssociation(
062                    (Association) params[0], (ClientState) params[1], (Directives) params[2]
063                );
064            }
065        },
066    
067        PRE_UPDATE_TOPIC(PreUpdateTopicListener.class) {
068            @Override
069            void deliver(Listener listener, Object... params) {
070                ((PreUpdateTopicListener) listener).preUpdateTopic(
071                    (Topic) params[0], (TopicModel) params[1], (Directives) params[2]
072                );
073            }
074        },
075        PRE_UPDATE_ASSOCIATION(PreUpdateAssociationListener.class) {
076            @Override
077            void deliver(Listener listener, Object... params) {
078                ((PreUpdateAssociationListener) listener).preUpdateAssociation(
079                    (Association) params[0], (AssociationModel) params[1], (Directives) params[2]
080                );
081            }
082        },
083    
084        POST_UPDATE_TOPIC(PostUpdateTopicListener.class) {
085            @Override
086            void deliver(Listener listener, Object... params) {
087                ((PostUpdateTopicListener) listener).postUpdateTopic(
088                    (Topic) params[0], (TopicModel) params[1], (TopicModel) params[2], (ClientState) params[3],
089                    (Directives) params[4]
090                );
091            }
092        },
093        POST_UPDATE_ASSOCIATION(PostUpdateAssociationListener.class) {
094            @Override
095            void deliver(Listener listener, Object... params) {
096                ((PostUpdateAssociationListener) listener).postUpdateAssociation(
097                    (Association) params[0], (AssociationModel) params[1], (ClientState) params[2], (Directives) params[3]
098                );
099            }
100        },
101    
102        PRE_DELETE_ASSOCIATION(PreDeleteAssociationListener.class) {
103            @Override
104            void deliver(Listener listener, Object... params) {
105                ((PreDeleteAssociationListener) listener).preDeleteAssociation(
106                    (Association) params[0], (Directives) params[1]
107                );
108            }
109        },
110        POST_DELETE_ASSOCIATION(PostDeleteAssociationListener.class) {
111            @Override
112            void deliver(Listener listener, Object... params) {
113                ((PostDeleteAssociationListener) listener).postDeleteAssociation(
114                    (Association) params[0], (Directives) params[1]
115                );
116            }
117        },
118    
119        SERVICE_REQUEST_FILTER(ServiceRequestFilterListener.class) {
120            @Override
121            void deliver(Listener listener, Object... params) {
122                ((ServiceRequestFilterListener) listener).serviceRequestFilter(
123                    (ContainerRequest) params[0]
124                );
125            }
126        },
127        SERVICE_RESPONSE_FILTER(ServiceResponseFilterListener.class) {
128            @Override
129            void deliver(Listener listener, Object... params) {
130                ((ServiceResponseFilterListener) listener).serviceResponseFilter(
131                    (ContainerResponse) params[0]
132                );
133            }
134        },
135        RESOURCE_REQUEST_FILTER(ResourceRequestFilterListener.class) {
136            @Override
137            void deliver(Listener listener, Object... params) {
138                ((ResourceRequestFilterListener) listener).resourceRequestFilter(
139                    (HttpServletRequest) params[0]
140                );
141            }
142        },
143    
144        PRE_SEND_TOPIC(PreSendTopicListener.class) {
145            @Override
146            void deliver(Listener listener, Object... params) {
147                ((PreSendTopicListener) listener).preSendTopic(
148                    (Topic) params[0], (ClientState) params[1]
149                );
150            }
151        },
152        PRE_SEND_ASSOCIATION(PreSendAssociationListener.class) {
153            @Override
154            void deliver(Listener listener, Object... params) {
155                ((PreSendAssociationListener) listener).preSendAssociation(
156                    (Association) params[0], (ClientState) params[1]
157                );
158            }
159        },
160        PRE_SEND_TOPIC_TYPE(PreSendTopicTypeListener.class) {
161            @Override
162            void deliver(Listener listener, Object... params) {
163                ((PreSendTopicTypeListener) listener).preSendTopicType(
164                    (TopicType) params[0], (ClientState) params[1]
165                );
166            }
167        },
168        PRE_SEND_ASSOCIATION_TYPE(PreSendAssociationTypeListener.class) {
169            @Override
170            void deliver(Listener listener, Object... params) {
171                ((PreSendAssociationTypeListener) listener).preSendAssociationType(
172                    (AssociationType) params[0], (ClientState) params[1]
173                );
174            }
175        },
176    
177        ALL_PLUGINS_ACTIVE(AllPluginsActiveListener.class) {
178            @Override
179            void deliver(Listener listener, Object... params) {
180                ((AllPluginsActiveListener) listener).allPluginsActive();
181            }
182        },
183    
184        // This event has a double nature:
185        //   a) it is fired regularily (see EmbeddedService.createTopicType()).
186        //   b) it is fired locally (see PluginImpl.introduceTopicTypesToPlugin()).
187        INTRODUCE_TOPIC_TYPE(IntroduceTopicTypeListener.class) {
188            @Override
189            void deliver(Listener listener, Object... params) {
190                ((IntroduceTopicTypeListener) listener).introduceTopicType(
191                    (TopicType) params[0], (ClientState) params[1]
192                );
193            }
194        },
195        // This event has a double nature:
196        //   a) it is fired regularily (see EmbeddedService.createAssociationType()).
197        //   b) it is fired locally (see PluginImpl.introduceAssociationTypesToPlugin()).
198        INTRODUCE_ASSOCIATION_TYPE(IntroduceAssociationTypeListener.class) {
199            @Override
200            void deliver(Listener listener, Object... params) {
201                ((IntroduceAssociationTypeListener) listener).introduceAssociationType(
202                    (AssociationType) params[0], (ClientState) params[1]
203                );
204            }
205        };
206    
207    
208        // ------------------------------------------------------------------------------------------------- Class Variables
209    
210        private static Map<String, CoreEvent> events;
211    
212        // ---------------------------------------------------------------------------------------------- Instance Variables
213    
214        final Class listenerInterface;
215    
216        // ---------------------------------------------------------------------------------------------------- Constructors
217    
218        private CoreEvent(Class listenerInterface) {
219            this.listenerInterface = listenerInterface;
220            // events.put(..);      // ### Doesn't compile: "illegal reference to static field from initializer".
221                                    // ### Enum constants are initialzed before other static fields.
222            put(this);              // ### Lazy initialization outside the constructor solves it.
223        }
224    
225        // ----------------------------------------------------------------------------------------- Package Private Methods
226    
227        abstract void deliver(Listener listener, Object... params);
228    
229        static CoreEvent fromListenerInterface(Class listenerInterface) {
230            return events.get(listenerInterface.getSimpleName());
231        }
232    
233        // ------------------------------------------------------------------------------------------------- Private Methods
234    
235        private void put(CoreEvent event) {
236            // ### must initialize lazily, see above
237            if (events == null) {
238                events = new HashMap();
239            }
240            //
241            events.put(event.listenerInterface.getSimpleName(), event);
242        }
243    }