You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ju...@apache.org on 2022/03/11 13:43:27 UTC

[jspwiki] 11/15: Introduce Engine Lifecycle Extensions - see https://jspwiki-wiki.apache.org/Wiki.jsp?page=HowToWriteAnEngineLifecycleExtension

This is an automated email from the ASF dual-hosted git repository.

juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git

commit 5a69bda0b0e04f39293e8070c0c7cc4fe5247083
Author: Juan Pablo Santos Rodríguez <ju...@gmail.com>
AuthorDate: Fri Mar 11 14:37:42 2022 +0100

    Introduce Engine Lifecycle Extensions - see https://jspwiki-wiki.apache.org/Wiki.jsp?page=HowToWriteAnEngineLifecycleExtension
---
 .../main/java/org/apache/wiki/api/core/Engine.java | 41 ++++++++++++-
 .../wiki/api/engine/EngineLifecycleExtension.java  | 67 ++++++++++++++++++++++
 .../api/engine/EngineLifecycleExtensionTest.java   | 56 ++++++++++++++++++
 .../engine/EngineLifecycleExtensionTestImpl.java   | 42 ++++++++++++++
 ...apache.wiki.api.engine.EngineLifecycleExtension |  1 +
 .../MarkdownSetupEngineLifecycleExtension.java     | 52 +++++++++++++++++
 ...apache.wiki.api.engine.EngineLifecycleExtension |  1 +
 .../MarkdownSetupEngineLifecycleExtensionTest.java | 42 ++++++++++++++
 8 files changed, 301 insertions(+), 1 deletion(-)

diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/core/Engine.java b/jspwiki-api/src/main/java/org/apache/wiki/api/core/Engine.java
index dab54a5..07e4fb4 100644
--- a/jspwiki-api/src/main/java/org/apache/wiki/api/core/Engine.java
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/core/Engine.java
@@ -19,7 +19,9 @@
 package org.apache.wiki.api.core;
 
 import org.apache.logging.log4j.LogManager;
+import org.apache.wiki.api.engine.EngineLifecycleExtension;
 import org.apache.wiki.api.exceptions.ProviderException;
+import org.apache.wiki.api.exceptions.WikiException;
 import org.apache.wiki.event.WikiEventListener;
 import org.apache.wiki.util.TextUtil;
 
@@ -37,6 +39,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Properties;
+import java.util.ServiceLoader;
 
 
 /**
@@ -413,7 +416,43 @@ public interface Engine {
     < T > T removeAttribute( String key );
 
     /**
-     * Signals that the Engine will be shut down by the servlet container.
+     * Initializes the {@code Engine}, notifying all the {@link EngineLifecycleExtension}s.
+     *
+     * @param properties Wiki configuration properties.
+     * @throws WikiException if something happens while setting up the {@code Engine}.
+     */
+    default void start( final Properties properties ) throws WikiException {
+        final ServiceLoader< EngineLifecycleExtension > loader = ServiceLoader.load( EngineLifecycleExtension.class );
+        for( final EngineLifecycleExtension extension : loader ) {
+            extension.onInit( properties );
+        }
+        initialize( properties );
+        for( final EngineLifecycleExtension extension : loader ) {
+            extension.onStart( this, properties );
+        }
+    }
+
+    /**
+     * Shuts down the {@code Engine}, notifying all the {@link EngineLifecycleExtension}s.
+     */
+    default void stop() {
+        final ServiceLoader< EngineLifecycleExtension > loader = ServiceLoader.load( EngineLifecycleExtension.class );
+        for( final EngineLifecycleExtension extension : loader ) {
+            extension.onShutdown( this, getWikiProperties() );
+        }
+        shutdown();
+    }
+
+    /**
+     * Sets up the application's running {@code Engine}.
+     *
+     * @param properties Wiki configuration properties.
+     * @throws WikiException if something happens while setting up the {@code Engine}.
+     */
+    void initialize( Properties properties ) throws WikiException;
+
+    /**
+     * Signals that the {@code Engine} will be shut down by the servlet container.
      */
     void shutdown();
 
diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/engine/EngineLifecycleExtension.java b/jspwiki-api/src/main/java/org/apache/wiki/api/engine/EngineLifecycleExtension.java
new file mode 100644
index 0000000..bf03fc3
--- /dev/null
+++ b/jspwiki-api/src/main/java/org/apache/wiki/api/engine/EngineLifecycleExtension.java
@@ -0,0 +1,67 @@
+/*
+    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.wiki.api.engine;
+
+import org.apache.wiki.api.core.Engine;
+
+import java.util.Properties;
+
+/**
+ * <p>SPI used to notify JSPWiki extensions about {@link Engine}'s initialization & shutdown, without having to deep
+ * dive on {@link Engine}'s internals.</p>
+ *
+ * <p>Examples of {@code EngineLifecycleExtension}'s use cases:
+ * <ul>
+ *   <li>Appending a plugin's classpath to {@code jspwiki.plugin.searchPath}, so it can be used as a drop-in, without further configuration.</li>
+ *   <li>Providing default parameters for a custom extension.</li>
+ *   <li>Setting up that expensive singleton, or disposing resources, without having to use or register a {@link org.apache.wiki.event.WikiEventListener WikiEventListener}.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>As a concrete example, the markdown module uses an {@code EngineLifecycleExtension} to set up all the required properties
+ * if {@code jspwiki.syntax=markdown} is provided on the {@code jspwiki[-custom].properties file}.</p>
+ *
+ * <p>All methods are provided with a {@code default}, do-nothing implementation, so specific EngineLifecycleExtensions only have
+ * to provide implementations for the methods they're really interested in.</p>
+ */
+public interface EngineLifecycleExtension {
+
+    /**
+     * Called before {@link Engine} initialization, after the wiki properties have been sought out.
+     *
+     * @param properties wiki configuration properties.
+     */
+    default void onInit( final Properties properties ) {}
+
+    /**
+     * Called after {@link Engine} initialization.
+     *
+     * @param properties wiki configuration properties.
+     * @param e JSPWiki's ready to be used {@link Engine}.
+     */
+    default void onStart( final Engine e, final Properties properties ) {}
+
+    /**
+     * Called before {@link Engine} shutdown.
+     * @param e JSPWiki's running {@link Engine}.
+     * @param properties wiki configuration properties.
+     */
+    default void onShutdown( final Engine e, final Properties properties ) {}
+
+}
diff --git a/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTest.java b/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTest.java
new file mode 100644
index 0000000..e9589f4
--- /dev/null
+++ b/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTest.java
@@ -0,0 +1,56 @@
+/*
+    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.wiki.api.engine;
+
+import org.apache.wiki.api.core.Engine;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.util.Properties;
+
+
+@ExtendWith( MockitoExtension.class )
+public class EngineLifecycleExtensionTest {
+
+    @Mock Engine engine;
+
+    @Test
+    void shouldInvokeEngineLifecycleExtensionTestImpl() throws Exception {
+        final Properties properties = new Properties();
+        Mockito.doAnswer( invocation -> {
+            final String actual = invocation.getArgument( 0, Properties.class ).getProperty( "test" );
+            Assertions.assertEquals( "onInit", actual );
+            return null; // void
+        } ).when( engine ).initialize( Mockito.any( Properties.class ) );
+        Mockito.doReturn( properties ).when( engine ).getWikiProperties();
+        Mockito.doCallRealMethod().when( engine ).start( Mockito.any( Properties.class ) );
+        Mockito.doCallRealMethod().when( engine ).stop();
+
+        engine.start( properties );
+        Assertions.assertEquals( "onStart", properties.getProperty( "test" ) );
+
+        engine.stop();
+        Assertions.assertEquals( "onShutdown", properties.getProperty( "test" ) );
+    }
+
+}
diff --git a/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTestImpl.java b/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTestImpl.java
new file mode 100644
index 0000000..5dbfddc
--- /dev/null
+++ b/jspwiki-api/src/test/java/org/apache/wiki/api/engine/EngineLifecycleExtensionTestImpl.java
@@ -0,0 +1,42 @@
+/*
+    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.wiki.api.engine;
+
+import org.apache.wiki.api.core.Engine;
+
+import java.util.Properties;
+
+public class EngineLifecycleExtensionTestImpl implements EngineLifecycleExtension {
+
+    /** {@inheritDoc */
+    public void onInit( final Properties properties ) {
+        properties.put( "test", "onInit" );
+    }
+
+    /** {@inheritDoc */
+    public void onStart( final Engine e, final Properties properties ) {
+        properties.put( "test", "onStart" );
+    }
+
+    /** {@inheritDoc */
+    public void onShutdown( final Engine e, final Properties properties ) {
+        properties.put( "test", "onShutdown" );
+    }
+    
+}
diff --git a/jspwiki-api/src/test/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension b/jspwiki-api/src/test/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension
new file mode 100644
index 0000000..9cfa45f
--- /dev/null
+++ b/jspwiki-api/src/test/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension
@@ -0,0 +1 @@
+org.apache.wiki.api.engine.EngineLifecycleExtensionTestImpl
\ No newline at end of file
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtension.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtension.java
new file mode 100644
index 0000000..76f3b43
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtension.java
@@ -0,0 +1,52 @@
+/*
+    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.wiki.markdown;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.wiki.api.engine.EngineLifecycleExtension;
+
+import java.util.Properties;
+
+
+/**
+ * {@link EngineLifecycleExtension} that sets up all the relevant properties to enable markdown syntax if the
+ * {@code jspwiki.syntax} property has been given, with the {@code markdown} value.
+ */
+public class MarkdownSetupEngineLifecycleExtension implements EngineLifecycleExtension {
+
+    private static final Logger LOG = LogManager.getLogger( MarkdownSetupEngineLifecycleExtension.class );
+
+    /** {@inheritDoc} */
+    @Override
+    public void onInit( final Properties properties ) {
+        if( "markdown".equalsIgnoreCase( properties.getProperty( "jspwiki.syntax" ) ) ) {
+            setWikiProperty( properties, "jspwiki.renderingManager.markupParser", "org.apache.wiki.parser.markdown.MarkdownParser" );
+            setWikiProperty( properties, "jspwiki.renderingManager.renderer", "org.apache.wiki.render.markdown.MarkdownRenderer" );
+            setWikiProperty( properties, "jspwiki.renderingManager.renderer.wysiwyg", "org.apache.wiki.render.markdown.MarkdownRenderer" );
+            setWikiProperty( properties, "jspwiki.syntax.decorator", "org.apache.wiki.htmltowiki.syntax.markdown.MarkdownSyntaxDecorator" );
+        }
+    }
+
+    void setWikiProperty( final Properties properties, final String key, final String value ) {
+        properties.setProperty( key, value );
+        LOG.info( "{} set to {}", key, value );
+    }
+
+}
diff --git a/jspwiki-markdown/src/main/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension b/jspwiki-markdown/src/main/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension
new file mode 100644
index 0000000..766735d
--- /dev/null
+++ b/jspwiki-markdown/src/main/resources/META-INF/services/org.apache.wiki.api.engine.EngineLifecycleExtension
@@ -0,0 +1 @@
+org.apache.wiki.markdown.MarkdownSetupEngineLifecycleExtension
\ No newline at end of file
diff --git a/jspwiki-markdown/src/test/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtensionTest.java b/jspwiki-markdown/src/test/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtensionTest.java
new file mode 100644
index 0000000..6c2aecb
--- /dev/null
+++ b/jspwiki-markdown/src/test/java/org/apache/wiki/markdown/MarkdownSetupEngineLifecycleExtensionTest.java
@@ -0,0 +1,42 @@
+/*
+    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.wiki.markdown;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Properties;
+
+public class MarkdownSetupEngineLifecycleExtensionTest {
+
+    @Test
+    void shouldSetUpMarkdownSupportIfJspwikiSyntaxPropertyIsGiven() {
+        final Properties properties = new Properties();
+        properties.put( "jspwiki.syntax", "markdown" );
+        final MarkdownSetupEngineLifecycleExtension sut = new MarkdownSetupEngineLifecycleExtension();
+        sut.onInit( properties );
+        Assertions.assertEquals( 5, properties.size() );
+        Assertions.assertEquals( "org.apache.wiki.parser.markdown.MarkdownParser", properties.getProperty( "jspwiki.renderingManager.markupParser" ) );
+
+        properties.clear();
+        sut.onInit( properties );
+        Assertions.assertEquals( 0, properties.size() );
+    }
+
+}