This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-starter-startup.git
commit 1af49b79971489e0e47b395af9a07970120ca331 Author: Carsten Ziegeler <[email protected]> AuthorDate: Thu Oct 5 11:38:40 2017 +0000 Move starter startup bundle git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1811187 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 74 ++++++++++ .../apache/sling/demo/startup/impl/Activator.java | 154 +++++++++++++++++++++ .../sling/demo/startup/impl/HttpStartupSetup.java | 122 ++++++++++++++++ .../sling/demo/startup/impl/StartupFilter.java | 62 +++++++++ 4 files changed, 412 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e988aff --- /dev/null +++ b/pom.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> + <!-- + Licensed to the Apache Software Foundation (ASF) under one or more contributor license + agreements. See the NOTICE file distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file to you 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>32</version> + <relativePath /> + </parent> + + <artifactId>org.apache.sling.demo.startup</artifactId> + <version>0.0.1-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>Apache Sling Demo Startup Bundle</name> + <description> + A module for handling demo startup. + </description> + + <properties> + <sling.java.version>8</sling.java.version> + </properties> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Activator> + org.apache.sling.demo.startup.impl.Activator + </Bundle-Activator> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.core</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.service.http.whiteboard</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.installer.api</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/demo/startup/impl/Activator.java b/src/main/java/org/apache/sling/demo/startup/impl/Activator.java new file mode 100644 index 0000000..65b012d --- /dev/null +++ b/src/main/java/org/apache/sling/demo/startup/impl/Activator.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.demo.startup.impl; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.sling.installer.api.info.InfoProvider; +import org.apache.sling.installer.api.info.InstallationState; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + +public class Activator implements BundleActivator { + + private final String[] REQUIRED_SERVICES = new String[] { + "org.apache.sling.api.auth.Authenticator", + "org.apache.sling.api.resource.ResourceResolverFactory", + "org.apache.sling.api.servlets.ServletResolver" + }; + + private volatile ServiceTracker<InfoProvider, InfoProvider> infoProviderTracker; + + private volatile HttpStartupSetup httpSetup; + + private final AtomicBoolean stopped = new AtomicBoolean(false); + + @Override + public void start(final BundleContext context) throws Exception { + this.httpSetup = new HttpStartupSetup(context); + this.httpSetup.start(); + + this.setupInfoProviderTracker(context); + } + + @Override + public void stop(final BundleContext context) throws Exception { + stopped.set(true); + this.stopInfoProviderTracker(); + + if ( this.httpSetup != null ) { + this.httpSetup.stop(); + this.httpSetup = null; + } + } + + /** + * Setup the info provider tracker + * @param context The bundle context + */ + private void setupInfoProviderTracker(final BundleContext context) { + this.infoProviderTracker = new ServiceTracker<>(context, InfoProvider.class, new ServiceTrackerCustomizer<InfoProvider, InfoProvider>() { + + private final AtomicInteger counter = new AtomicInteger(); + + private final Timer timer = new Timer(); + + @Override + public InfoProvider addingService(final ServiceReference<InfoProvider> reference) { + if ( stopped.get() ) { + return null; + } + final InfoProvider service = context.getService(reference); + if ( counter.incrementAndGet() == 1 ) { + startCheck(service); + } + return service; + } + + @Override + public void modifiedService(final ServiceReference<InfoProvider> reference, final InfoProvider service) { + // nothing to do + } + + @Override + public void removedService(final ServiceReference<InfoProvider> reference, final InfoProvider service) { + if ( counter.decrementAndGet() == 0 ) { + stopCheck(); + } + context.ungetService(reference); + } + + private void startCheck(final InfoProvider service) { + final TimerTask task = new TimerTask() { + @Override + public void run() { + final InstallationState state = service.getInstallationState(); + if ( state.getActiveResources().isEmpty() + && state.getUntransformedResources().isEmpty() + && checkServices(context)) { + + httpSetup.stop(); + this.cancel(); + } + } + }; + timer.schedule(task, 1000, 1000); + } + + private void stopCheck() { + timer.cancel(); + if ( !stopped.get() ) { + httpSetup.start(); + } + } + + + }); + this.infoProviderTracker.open(); + } + + /** + * Stop the info provider tracker + */ + private void stopInfoProviderTracker() { + if ( infoProviderTracker != null ) { + infoProviderTracker.close(); + infoProviderTracker = null; + } + } + + private boolean checkServices(final BundleContext context) { + for(final String name : REQUIRED_SERVICES) { + final ServiceReference<?> ref = context.getServiceReference(name); + if ( ref == null ) { + return false; + } + final Object service = context.getService(ref); + if ( service == null ) { + return false; + } + context.ungetService(ref); + } + return true; + } +} diff --git a/src/main/java/org/apache/sling/demo/startup/impl/HttpStartupSetup.java b/src/main/java/org/apache/sling/demo/startup/impl/HttpStartupSetup.java new file mode 100644 index 0000000..f6b9477 --- /dev/null +++ b/src/main/java/org/apache/sling/demo/startup/impl/HttpStartupSetup.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.demo.startup.impl; + +import java.util.Dictionary; +import java.util.Hashtable; + +import javax.servlet.Filter; +import javax.servlet.Servlet; +import javax.servlet.http.HttpServlet; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.http.context.ServletContextHelper; +import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; + +public class HttpStartupSetup { + + private static final String CONTEXT_NAME = "internal.sling.setup"; + + private volatile ServiceRegistration<ServletContextHelper> httpContextRegistration; + + private volatile ServiceRegistration<Servlet> defaultServletRegistration; + + private volatile ServiceRegistration<Filter> startupFilterRegistration; + + private final BundleContext context; + + public HttpStartupSetup(final BundleContext context) { + this.context = context; + } + + public void start() { + this.registerHttpContext(); + this.registerStartupFilter(); + } + + public void stop() { + this.unregisterStartupFilter(); + this.unregisterHttpContext(); + } + + /** + * Register the http context + * @param context The bundle context + */ + private void registerHttpContext() { + final Dictionary<String, Object> properties = new Hashtable<>(); + properties.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, CONTEXT_NAME); + properties.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/"); + properties.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); + + this.httpContextRegistration = context.registerService(ServletContextHelper.class, + new ServletContextHelper() { + }, properties); + + final Dictionary<String, Object> servletProps = new Hashtable<>(); + servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, + "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + CONTEXT_NAME + ")"); + servletProps.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/"); + + this.defaultServletRegistration = context.registerService(Servlet.class, new HttpServlet() { + + private static final long serialVersionUID = 1L; + + }, servletProps); + } + + /** + * Unregister the http context + */ + private void unregisterHttpContext() { + if ( this.defaultServletRegistration != null ) { + this.defaultServletRegistration.unregister(); + this.defaultServletRegistration = null; + } + if ( this.httpContextRegistration != null ) { + this.httpContextRegistration.unregister(); + this.httpContextRegistration = null; + } + } + + /** + * Register the startup filter + * @param context The bundle context + */ + private void registerStartupFilter() { + final Dictionary<String, Object> properties = new Hashtable<>(); + properties.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, + "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=" + CONTEXT_NAME + ")"); + properties.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/"); + properties.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); + + this.startupFilterRegistration = context.registerService(Filter.class, + new StartupFilter(), properties); + } + + /** + * Unregister the startup filter + */ + private void unregisterStartupFilter() { + if ( this.startupFilterRegistration != null ) { + this.startupFilterRegistration.unregister(); + this.startupFilterRegistration = null; + } + } +} diff --git a/src/main/java/org/apache/sling/demo/startup/impl/StartupFilter.java b/src/main/java/org/apache/sling/demo/startup/impl/StartupFilter.java new file mode 100644 index 0000000..8819505 --- /dev/null +++ b/src/main/java/org/apache/sling/demo/startup/impl/StartupFilter.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.sling.demo.startup.impl; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; + +public class StartupFilter implements Filter { + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + // nothing to do + } + + @Override + public void doFilter(final ServletRequest request, + final ServletResponse response, + final FilterChain chain) + throws IOException, ServletException { + response.setContentType("text/html"); + response.setCharacterEncoding("utf-8"); + ((HttpServletResponse)response).setHeader("Cache-Control", "no-store"); + final PrintWriter pw = response.getWriter(); + + pw.println("<html><head>"); + pw.println("<META HTTP-EQUIV=\"refresh\" CONTENT=\"5\">"); + pw.println("<title>Apache Sling...</title></head>"); + pw.println("<body>"); + pw.println("<h1>Apache Sling is starting up....</h1>"); + pw.println("</body>"); + pw.println("</html>"); + + pw.flush(); + } + + @Override + public void destroy() { + // nothing to do + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
