PackageManagerHtmlMessageCall.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2014 wcm.io
  6.  * %%
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  * #L%
  19.  */
  20. package io.wcm.tooling.commons.packmgr.httpaction;

  21. import java.io.IOException;
  22. import java.util.regex.Pattern;

  23. import org.apache.commons.lang3.StringUtils;
  24. import org.apache.http.HttpStatus;
  25. import org.apache.http.client.methods.CloseableHttpResponse;
  26. import org.apache.http.client.methods.HttpRequestBase;
  27. import org.apache.http.client.protocol.HttpClientContext;
  28. import org.apache.http.impl.client.CloseableHttpClient;
  29. import org.apache.http.util.EntityUtils;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;

  32. import io.wcm.tooling.commons.packmgr.PackageManagerException;
  33. import io.wcm.tooling.commons.packmgr.PackageManagerHttpActionException;
  34. import io.wcm.tooling.commons.packmgr.PackageManagerProperties;

  35. /**
  36.  * Call that parses a packager manager HTML response and returns the contained message as plain text.
  37.  */
  38. public final class PackageManagerHtmlMessageCall implements HttpCall<String> {

  39.   private final CloseableHttpClient httpClient;
  40.   private final HttpClientContext context;
  41.   private final HttpRequestBase method;
  42.   private final PackageManagerProperties props;

  43.   private static final String PACKAGE_MANAGER_ERROR_INDICATION = "Error during processing.";
  44.   private static final Logger log = LoggerFactory.getLogger(PackageManagerHtmlMessageCall.class);

  45.   private static final Pattern HTML_STYLE = Pattern.compile("<style[^<>]*>[^<>]*</style>", Pattern.MULTILINE | Pattern.DOTALL);
  46.   private static final Pattern HTML_JAVASCRIPT = Pattern.compile("<script[^<>]*>[^<>]*</script>", Pattern.MULTILINE | Pattern.DOTALL);
  47.   private static final Pattern TEXT_LINE_BREAKS = Pattern.compile("[\n\r]");
  48.   private static final Pattern HTML_LINE_BREAKS = Pattern.compile("(<br/?>|</p>|</h\\d>)");
  49.   private static final Pattern HTML_ANYTAG = Pattern.compile("<[^<>]*>");

  50.   /**
  51.    * @param httpClient HTTP client
  52.    * @param context HTTP client context
  53.    * @param method HTTP method
  54.    * @param props Package manager properties
  55.    */
  56.   public PackageManagerHtmlMessageCall(CloseableHttpClient httpClient, HttpClientContext context, HttpRequestBase method,
  57.       PackageManagerProperties props) {
  58.     this.httpClient = httpClient;
  59.     this.context = context;
  60.     this.method = method;
  61.     this.props = props;
  62.   }

  63.   @Override
  64.   public String execute() {
  65.     log.debug("Call URL: {}", method.getURI());

  66.     try (CloseableHttpResponse response = httpClient.execute(method, context)) {
  67.       String responseString = EntityUtils.toString(response.getEntity());

  68.       if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {

  69.         // debug output whole xml
  70.         log.trace("CRX Package Manager Response:\n{}", responseString);

  71.         // remove all HTML tags and special content
  72.         responseString = HTML_STYLE.matcher(responseString).replaceAll("");
  73.         responseString = HTML_JAVASCRIPT.matcher(responseString).replaceAll("");
  74.         responseString = TEXT_LINE_BREAKS.matcher(responseString).replaceAll("");
  75.         responseString = HTML_LINE_BREAKS.matcher(responseString).replaceAll("\n");
  76.         responseString = HTML_ANYTAG.matcher(responseString).replaceAll("");
  77.         responseString = StringUtils.replace(responseString, "&nbsp;", " ");
  78.         responseString = "\n" + StringUtils.trim(responseString);

  79.         if (StringUtils.equalsIgnoreCase(props.getPackageManagerOutputLogLevel(), "debug")) {
  80.           log.debug(responseString);
  81.         }
  82.         else {
  83.           log.info(responseString);
  84.         }

  85.         if (StringUtils.contains(responseString, PACKAGE_MANAGER_ERROR_INDICATION)) {
  86.           throw new PackageManagerException("Package installation failed: " + PACKAGE_MANAGER_ERROR_INDICATION + "\n"
  87.               + method.getURI());
  88.         }

  89.         return responseString;
  90.       }
  91.       else {
  92.         throw PackageManagerHttpActionException.forHttpError(method.getURI().toString(), response.getStatusLine(), responseString);
  93.       }

  94.     }
  95.     catch (IOException ex) {
  96.       throw PackageManagerHttpActionException.forIOException(method.getURI().toString(), ex);
  97.     }
  98.   }

  99. }