Content of file DefaultEmbeddedServer.java.html

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>DefaultEmbeddedServer.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Zephyr - UI Content Editor</a> &gt; <a href="../index.html" class="el_bundle">it-tidalwave-northernwind-rca-embeddedserver</a> &gt; <a href="index.source.html" class="el_package">it.tidalwave.northernwind.rca.embeddedserver.impl</a> &gt; <span class="el_source">DefaultEmbeddedServer.java</span></div><h1>DefaultEmbeddedServer.java</h1><pre class="source lang-java linenums"><span class="fc" id="L1">/*</span>
 * #%L
 * *********************************************************************************************************************
 *
 * NorthernWind - lightweight CMS
 * http://northernwind.tidalwave.it - git clone git@bitbucket.org:tidalwave/northernwind-rca-src.git
 * %%
 * Copyright (C) 2013 - 2021 Tidalwave s.a.s. (http://tidalwave.it)
 * %%
 * *********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); 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 &quot;AS IS&quot; 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.
 *
 * *********************************************************************************************************************
 *
 *
 * *********************************************************************************************************************
 * #L%
 */
package it.tidalwave.northernwind.rca.embeddedserver.impl;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.FileNotFoundException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import it.tidalwave.util.annotation.VisibleForTesting;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ClassPathResource;
import org.eclipse.jetty.server.Server;
import it.tidalwave.messagebus.annotation.ListensTo;
import it.tidalwave.messagebus.annotation.SimpleMessageSubscriber;
import it.tidalwave.northernwind.core.impl.filter.LibraryLinkMacroFilter;
import it.tidalwave.northernwind.core.impl.filter.MediaLinkMacroFilter;
import it.tidalwave.northernwind.core.model.MimeTypeResolver;
import it.tidalwave.northernwind.core.model.ResourceFile;
import it.tidalwave.northernwind.core.model.ResourceFileSystem;
import it.tidalwave.northernwind.rca.embeddedserver.EmbeddedServer;
import it.tidalwave.northernwind.rca.ui.event.OpenSiteEvent;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import static java.util.stream.Collectors.joining;

/***********************************************************************************************************************
 *
 * @author  Fabrizio Giudici
 *
 **********************************************************************************************************************/
<span class="pc bpc" id="L64" title="1 of 2 branches missed.">@SimpleMessageSubscriber @RequiredArgsConstructor @Slf4j</span>
public class DefaultEmbeddedServer implements EmbeddedServer
  {
    @Nonnull
    private final MimeTypeResolver mimeTypeResolver;

<span class="pc" id="L70">    @Getter @Setter</span>
    private int port = 12345;

    @CheckForNull
    @VisibleForTesting Server server;

<span class="fc" id="L76">    private final Map&lt;String, Document&gt; documentMapByUrl = new HashMap&lt;&gt;();</span>

    @CheckForNull
    private ResourceFileSystem fileSystem;

    /*******************************************************************************************************************
     *
     *
     *
     ******************************************************************************************************************/
<span class="fc" id="L86">    private final ServletAdapter servlet = new ServletAdapter()</span>
<span class="fc" id="L87">      {</span>
        private static final long serialVersionUID = -2887261966375531858L;

<span class="fc" id="L90">        private final MediaLinkMacroFilter mediaLinkMacroFilter = new MediaLinkMacroFilter();</span>
<span class="fc" id="L91">        private final LibraryLinkMacroFilter libraryLinkMacroFilter = new LibraryLinkMacroFilter();</span>

        @Override
        protected void doGet (@Nonnull final HttpServletRequest request,
                              @Nonnull final HttpServletResponse response)
          throws ServletException, IOException
          {
<span class="fc" id="L98">            String uri = request.getRequestURI();</span>
<span class="fc" id="L99">            log.debug(&quot;doGet({})&quot;, uri);</span>
            // FIXME: use a pipeline for handling those requests - eventually integrate support already in Site
use a pipeline for handling those requests - eventually integrate support already in Site
<span class="fc" id="L102"> uri = mediaLinkMacroFilter.filter(uri, &quot;&quot;);</span> <span class="fc" id="L103"> uri = libraryLinkMacroFilter.filter(uri, &quot;&quot;);</span> <span class="fc" id="L104"> uri = uri.replace(&quot;//&quot;, &quot;/&quot;); // Aloha puts a leading / before the macro</span> <span class="fc" id="L105"> log.debug(&quot;&gt;&gt;&gt; filtered {}&quot;, uri);</span> <span class="pc bpc" id="L107" title="1 of 2 branches missed."> if (uri.startsWith(&quot;/nwa/&quot;)) // FIXME - and use ResourcePath</span> { <span class="nc" id="L109"> serveEditorResources(uri, response);</span> } <span class="pc bpc" id="L112" title="2 of 4 branches missed."> else if (uri.startsWith(&quot;/library/&quot;) || uri.startsWith(&quot;/media/&quot;)) // FIXME - and use ResourcePath</span> { <span class="nc" id="L114"> serveContentResources(uri, response);</span> } else { <span class="fc" id="L119"> serveRegisteredResources(uri, response);</span> } <span class="fc" id="L121"> }</span> @Override protected void doPut (@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response) throws ServletException, IOException { <span class="nc" id="L128"> final String uri = request.getRequestURI();</span> <span class="nc" id="L129"> log.debug(&quot;doPut({})&quot;, uri);</span> <span class="nc" id="L130"> updateRegisteredResource(request, response);</span> <span class="nc" id="L131"> }</span> }; /******************************************************************************************************************* * * * * ******************************************************************************************************************/ @VisibleForTesting void onOpenSite (@ListensTo @Nonnull final OpenSiteEvent event) { <span class="nc" id="L142"> log.debug(&quot;onOpenSite({})&quot;, event);</span> <span class="nc" id="L143"> fileSystem = event.getFileSystem();</span> <span class="nc" id="L144"> }</span> /******************************************************************************************************************* * * * * ******************************************************************************************************************/ @PostConstruct public void start() { try { <span class="fc" id="L157"> log.info(&quot;Starting webserver on port {}...&quot;, port);</span> <span class="fc" id="L158"> server = new Server(port);</span> <span class="fc" id="L159"> server.setHandler(servlet.asHandler());</span> <span class="fc" id="L160"> server.start();</span> <span class="fc" id="L161"> log.info(&quot;&gt;&gt;&gt;&gt; started&quot;);</span> } <span class="nc" id="L163"> catch (Exception e)</span> { <span class="nc" id="L165"> log.error(&quot;&quot;, e);</span> <span class="fc" id="L166"> }</span> <span class="fc" id="L167"> }</span> /******************************************************************************************************************* * * * * ******************************************************************************************************************/ @PreDestroy public void stop() { try { <span class="pc bpc" id="L180" title="3 of 6 branches missed."> if ((server != null) &amp;&amp; !server.isStopping() &amp;&amp; !server.isStopped())</span> { <span class="fc" id="L182"> log.info(&quot;Stopping webserver...&quot;);</span> <span class="fc" id="L183"> server.stop();</span> <span class="fc" id="L184"> log.info(&quot;&gt;&gt;&gt;&gt; stopped&quot;);</span> } } <span class="nc" id="L187"> catch (Exception e)</span> { <span class="nc" id="L189"> log.error(&quot;&quot;, e);</span> <span class="fc" id="L190"> }</span> <span class="fc" id="L191"> }</span> /******************************************************************************************************************* * * * * ******************************************************************************************************************/ @Override @Nonnull public String putDocument (@Nonnull final String path, @Nonnull final Document document) { <span class="fc" id="L202"> documentMapByUrl.put(path, document);</span> <span class="fc" id="L203"> return String.format(&quot;http://localhost:%d%s&quot;, port, path);</span> } /******************************************************************************************************************* * * * ******************************************************************************************************************/ private void serveEditorResources (@Nonnull final String uri, @Nonnull final HttpServletResponse response) throws IOException { try { <span class="nc" id="L217"> final byte[] resource = loadResource(uri);</span> <span class="nc" id="L218"> response.setCharacterEncoding(&quot;&quot;);</span> <span class="nc" id="L219"> response.setContentType(mimeTypeResolver.getMimeType(uri));</span> <span class="nc" id="L220"> response.setStatus(HttpServletResponse.SC_OK);</span> <span class="nc" id="L221"> response.getOutputStream().write(resource);</span> } <span class="nc" id="L223"> catch (FileNotFoundException e)</span> { <span class="nc" id="L225"> log.warn(&quot;2 - Not found: {}&quot;, uri);</span> <span class="nc" id="L226"> response.setStatus(HttpServletResponse.SC_NOT_FOUND);</span> <span class="nc" id="L227"> }</span> <span class="nc" id="L228"> }</span> /******************************************************************************************************************* * * * ******************************************************************************************************************/ private void serveContentResources (@Nonnull final String uri, @Nonnull final HttpServletResponse response) throws IOException { <span class="nc" id="L239"> log.debug(&quot;serveLibraryResources({})&quot;, uri);</span> // don't bother when there's no opened Site <span class="nc bnc" id="L242" title="All 2 branches missed."> if (fileSystem == null)</span> { <span class="nc" id="L244"> response.setStatus(HttpServletResponse.SC_OK);</span> } else { <span class="nc" id="L248"> final ResourceFile file = fileSystem.findFileByPath(&quot;/content&quot; + uri); // FIXME</span> <span class="nc bnc" id="L250" title="All 2 branches missed."> if (file == null)</span> { <span class="nc" id="L252"> log.warn(&quot;5 - Not found: {}&quot;, &quot;/content&quot; + uri);</span> <span class="nc" id="L253"> response.setStatus(HttpServletResponse.SC_NOT_FOUND);</span> <span class="nc" id="L254"> return;</span> } <span class="nc" id="L257"> final String mimeType = file.getMimeType();</span> <span class="nc" id="L258"> response.setContentType(mimeType);</span> <span class="nc" id="L259"> response.setStatus(HttpServletResponse.SC_OK);</span> <span class="nc bnc" id="L261" title="All 2 branches missed."> if (mimeType.startsWith(&quot;image&quot;))</span> { <span class="nc" id="L263"> response.getOutputStream().write(file.asBytes());</span> } else { <span class="nc" id="L267"> response.setCharacterEncoding(&quot;UTF-8&quot;);</span> <span class="nc" id="L268"> response.getWriter().write(file.asText(&quot;UTF-8&quot;));</span> } } <span class="nc" id="L271"> }</span> /******************************************************************************************************************* * * * ******************************************************************************************************************/ private void serveRegisteredResources (@Nonnull final String uri, @Nonnull final HttpServletResponse response) throws IOException { <span class="fc" id="L282"> final Document document = documentMapByUrl.get(uri);</span> <span class="fc bfc" id="L284" title="All 2 branches covered."> if (document == null)</span> { <span class="fc" id="L286"> log.warn(&quot;1 - Not found: {}&quot;, uri);</span> <span class="fc" id="L287"> response.setStatus(HttpServletResponse.SC_NOT_FOUND);</span> } else { <span class="fc" id="L291"> response.setCharacterEncoding(&quot;UTF-8&quot;);</span> <span class="fc" id="L292"> response.setContentType(document.getMimeType());</span> <span class="fc" id="L293"> response.setStatus(HttpServletResponse.SC_OK);</span> <span class="fc" id="L294"> response.getWriter().write(document.getContent());</span> } <span class="fc" id="L296"> }</span> /******************************************************************************************************************* * * * ******************************************************************************************************************/ private void updateRegisteredResource (@Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response) throws IOException { <span class="nc" id="L307"> final String uri = request.getRequestURI();</span> <span class="nc" id="L308"> final String body = request.getReader().lines().collect(joining(&quot;\n&quot;));</span> <span class="nc" id="L310"> final Document document = documentMapByUrl.get(uri);</span> <span class="nc bnc" id="L312" title="All 2 branches missed."> if (document == null)</span> { <span class="nc" id="L314"> log.warn(&quot;3 - Not found: {}&quot;, uri);</span> <span class="nc" id="L315"> response.setStatus(HttpServletResponse.SC_NOT_FOUND);</span> } else { <span class="nc" id="L319"> document.update(body);</span> <span class="nc" id="L320"> response.setStatus(HttpServletResponse.SC_OK);</span> } <span class="nc" id="L322"> }</span> /******************************************************************************************************************* * * * ******************************************************************************************************************/ @Nonnull @VisibleForTesting byte[] loadResource (@Nonnull final String path) throws IOException { <span class="nc" id="L333"> final ClassPathResource resource = new ClassPathResource(path);</span> <span class="nc" id="L335"> try (final DataInputStream is = new DataInputStream(resource.getInputStream()))</span> { <span class="nc" id="L337"> return is.readAllBytes();</span> } } } </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.7.202105040129</span></div></body></html>