aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <legioth@gmail.com>2016-12-02 16:17:15 +0200
committerDenis <denis@vaadin.com>2016-12-02 17:17:15 +0300
commite746963efb1135e256da78cdd8cc24c88fdfd194 (patch)
tree5f86508bef50b4b7811ec8c7a597e737486449eb
parent54a6eef91cb2f0b8b7d65661162257711a2d6e2a (diff)
downloadvaadin-framework-e746963efb1135e256da78cdd8cc24c88fdfd194.tar.gz
vaadin-framework-e746963efb1135e256da78cdd8cc24c88fdfd194.zip
Introduce VaadinServiceInitListener (#18628) (#79)
-rw-r--r--server/src/main/java/com/vaadin/server/ServiceInitEvent.java79
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinService.java30
-rw-r--r--server/src/main/java/com/vaadin/server/VaadinServiceInitListener.java47
-rw-r--r--uitest/src/main/java/com/vaadin/tests/applicationservlet/ServiceInitListeners.java28
-rw-r--r--uitest/src/main/java/com/vaadin/tests/applicationservlet/TestingServiceInitListener.java56
-rw-r--r--uitest/src/main/resources/META-INF/services/com.vaadin.server.VaadinServiceInitListener1
-rw-r--r--uitest/src/test/java/com/vaadin/tests/applicationservlet/ServiceInitListenersTest.java39
7 files changed, 280 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/server/ServiceInitEvent.java b/server/src/main/java/com/vaadin/server/ServiceInitEvent.java
new file mode 100644
index 0000000000..b488c32e5e
--- /dev/null
+++ b/server/src/main/java/com/vaadin/server/ServiceInitEvent.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * 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 com.vaadin.server;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EventObject;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Event fired to {@link VaadinServiceInitListener} when a {@link VaadinService}
+ * is being initialized.
+ * <p>
+ * This event can also be used to add {@link RequestHandler}s that will be used
+ * by the {@code VaadinService} for handling all requests.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ServiceInitEvent extends EventObject {
+
+ private List<RequestHandler> addedRequestHandlers = new ArrayList<>();
+
+ /**
+ * Creates a new service init event for a given {@link VaadinService} and
+ * the {@link RequestHandler} that will be used by the service.
+ *
+ * @param service
+ * the Vaadin service of this request
+ */
+ public ServiceInitEvent(VaadinService service) {
+ super(service);
+ }
+
+ /**
+ * Adds a new request handler that will be used by this service. The added
+ * handler will be run before any of the framework's own request handlers,
+ * but the ordering relative to other custom handlers is not guaranteed.
+ *
+ * @param requestHandler
+ * the request handler to add, not <code>null</code>
+ */
+ public void addRequestHandler(RequestHandler requestHandler) {
+ Objects.requireNonNull(requestHandler,
+ "Request handler cannot be null");
+
+ addedRequestHandlers.add(requestHandler);
+ }
+
+ /**
+ * Gets an unmodifiable list of all custom request handlers that have been
+ * added for the service.
+ *
+ * @return the current list of added request handlers
+ */
+ public List<RequestHandler> getAddedRequestHandlers() {
+ return Collections.unmodifiableList(addedRequestHandlers);
+ }
+
+ @Override
+ public VaadinService getSource() {
+ return (VaadinService) super.getSource();
+ }
+
+}
diff --git a/server/src/main/java/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java
index 70a60a4f1f..d07413f237 100644
--- a/server/src/main/java/com/vaadin/server/VaadinService.java
+++ b/server/src/main/java/com/vaadin/server/VaadinService.java
@@ -31,9 +31,11 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -191,13 +193,41 @@ public abstract class VaadinService implements Serializable {
*/
public void init() throws ServiceException {
List<RequestHandler> handlers = createRequestHandlers();
+
+ ServiceInitEvent event = new ServiceInitEvent(this);
+
+ Iterator<VaadinServiceInitListener> initListeners = getServiceInitListeners();
+ while (initListeners.hasNext()) {
+ initListeners.next().serviceInit(event);
+ }
+
+ handlers.addAll(event.getAddedRequestHandlers());
+
Collections.reverse(handlers);
+
requestHandlers = Collections.unmodifiableCollection(handlers);
initialized = true;
}
/**
+ * Gets all available service init listeners. A custom Vaadin service
+ * implementation can override this method to discover init listeners in
+ * some other way in addition to the default implementation that uses
+ * {@link ServiceLoader}. This could for example be used to allow defining
+ * an init listener as an OSGi service or as a Spring bean.
+ *
+ * @since
+ *
+ * @return an iterator of available service init listeners
+ */
+ protected Iterator<VaadinServiceInitListener> getServiceInitListeners() {
+ ServiceLoader<VaadinServiceInitListener> loader = ServiceLoader
+ .load(VaadinServiceInitListener.class, getClassLoader());
+ return loader.iterator();
+ }
+
+ /**
* Called during initialization to add the request handlers for the service.
* Note that the returned list will be reversed so the last handler will be
* called first. This enables overriding this method and using add on the
diff --git a/server/src/main/java/com/vaadin/server/VaadinServiceInitListener.java b/server/src/main/java/com/vaadin/server/VaadinServiceInitListener.java
new file mode 100644
index 0000000000..98959f0571
--- /dev/null
+++ b/server/src/main/java/com/vaadin/server/VaadinServiceInitListener.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * 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 com.vaadin.server;
+
+import java.io.Serializable;
+import java.util.EventListener;
+import java.util.ServiceLoader;
+
+/**
+ * Listener for {@link VaadinService} initialization events. The listener can
+ * add listeners and request handlers the service.
+ * <p>
+ * Listener instances are by default discovered and instantiated using
+ * {@link ServiceLoader}. This means that all implementations must have a
+ * zero-argument constructor and the fully qualified name of the implementation
+ * class must be listed on a separate line in a
+ * META-INF/services/com.vaadin.server.VaadinServiceInitListener file present in
+ * the jar file containing the implementation class.
+ * <p>
+ * Integrations for specific runtime environments, such as OSGi or Spring, might
+ * also provide other ways of discovering listeners.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface VaadinServiceInitListener extends EventListener, Serializable {
+ /**
+ * Run when a {@link VaadinService} instance is initialized.
+ *
+ * @param event
+ * the service initialization event
+ */
+ void serviceInit(ServiceInitEvent event);
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/applicationservlet/ServiceInitListeners.java b/uitest/src/main/java/com/vaadin/tests/applicationservlet/ServiceInitListeners.java
new file mode 100644
index 0000000000..4ecb7cf0f0
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/applicationservlet/ServiceInitListeners.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.applicationservlet;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+
+public class ServiceInitListeners extends AbstractTestUIWithLog {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ log("Init count: " + TestingServiceInitListener.getInitCount());
+ log("Request count: " + TestingServiceInitListener.getRequestCount());
+ }
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/applicationservlet/TestingServiceInitListener.java b/uitest/src/main/java/com/vaadin/tests/applicationservlet/TestingServiceInitListener.java
new file mode 100644
index 0000000000..d0685ad975
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/applicationservlet/TestingServiceInitListener.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.applicationservlet;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.vaadin.server.RequestHandler;
+import com.vaadin.server.ServiceInitEvent;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinResponse;
+import com.vaadin.server.VaadinServiceInitListener;
+import com.vaadin.server.VaadinSession;
+
+public class TestingServiceInitListener implements VaadinServiceInitListener {
+
+ private static AtomicInteger initCount = new AtomicInteger();
+ private static AtomicInteger requestCount = new AtomicInteger();
+
+ @Override
+ public void serviceInit(ServiceInitEvent event) {
+ initCount.incrementAndGet();
+
+ event.addRequestHandler(new RequestHandler() {
+ @Override
+ public boolean handleRequest(VaadinSession session,
+ VaadinRequest request, VaadinResponse response)
+ throws IOException {
+ requestCount.incrementAndGet();
+ return false;
+ }
+ });
+ }
+
+ public static int getInitCount() {
+ return initCount.get();
+ }
+
+ public static int getRequestCount() {
+ return requestCount.get();
+ }
+
+}
diff --git a/uitest/src/main/resources/META-INF/services/com.vaadin.server.VaadinServiceInitListener b/uitest/src/main/resources/META-INF/services/com.vaadin.server.VaadinServiceInitListener
new file mode 100644
index 0000000000..ea3d467dab
--- /dev/null
+++ b/uitest/src/main/resources/META-INF/services/com.vaadin.server.VaadinServiceInitListener
@@ -0,0 +1 @@
+com.vaadin.tests.applicationservlet.TestingServiceInitListener
diff --git a/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServiceInitListenersTest.java b/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServiceInitListenersTest.java
new file mode 100644
index 0000000000..2c9403acdb
--- /dev/null
+++ b/uitest/src/test/java/com/vaadin/tests/applicationservlet/ServiceInitListenersTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * 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 com.vaadin.tests.applicationservlet;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class ServiceInitListenersTest extends SingleBrowserTest {
+
+ @Test
+ public void testServiceInitListenerTriggered() {
+ openTestURL();
+
+ Assert.assertNotEquals(getLogRow(0), 0, extractCount(getLogRow(0)));
+ Assert.assertNotEquals(getLogRow(1), 0, extractCount(getLogRow(1)));
+ }
+
+ private int extractCount(String logRow) {
+ // Assuming row pattern is "label: 1"
+ String substring = logRow.replaceAll("[^:]*:\\s*", "");
+ return Integer.parseInt(substring);
+ }
+
+}