View Javadoc
1   /*
2    * Copyright (c) 2011-2022, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.w3c;
31  
32  import com.jcabi.manifests.Manifests;
33  import java.io.ByteArrayOutputStream;
34  import java.io.IOException;
35  import java.net.URI;
36  import java.nio.charset.Charset;
37  import java.nio.charset.StandardCharsets;
38  import java.util.List;
39  import lombok.ToString;
40  import org.apache.http.entity.ContentType;
41  import org.apache.http.entity.mime.MultipartEntityBuilder;
42  
43  /**
44   * Abstract implementation of (X)HTML validator.
45   *
46   * @since 0.1
47   */
48  @ToString
49  @SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
50  abstract class AbstractBaseValidator {
51  
52      /**
53       * User agent.
54       */
55      protected static final String USER_AGENT = String.format(
56          "ReXSL-W3C %s %s %s",
57          Manifests.read("JCabi-Version"),
58          Manifests.read("JCabi-Build"),
59          Manifests.read("JCabi-Date")
60      );
61  
62      /**
63       * Boundary for HTTP POST form data (just some random data).
64       */
65      protected static final String BOUNDARY = "vV9olNqRj00PC4OIlM7";
66  
67      /**
68       * Convert HTML to HTTP FORM entity.
69       * @param name Name of HTTP form field
70       * @param content The content of it
71       * @param type Media type of it
72       * @return The HTTP post body
73       * @throws IOException if fails
74       */
75      protected static String entity(final String name, final String content,
76          final String type) throws IOException {
77          final ByteArrayOutputStream baos = new ByteArrayOutputStream();
78          MultipartEntityBuilder.create()
79              .setStrictMode()
80              .setCharset(StandardCharsets.UTF_8)
81              .setBoundary(AbstractBaseValidator.BOUNDARY)
82              .addBinaryBody(
83                  name,
84                  content.getBytes(StandardCharsets.UTF_8),
85                  ContentType.create(type, StandardCharsets.UTF_8),
86                  "file"
87              )
88              .addTextBody("output", "soap12")
89              .build()
90              .writeTo(baos);
91          return baos.toString(StandardCharsets.UTF_8.toString());
92      }
93  
94      /**
95       * Build a success response.
96       * @param type Media type of resource just processed
97       * @return The validation response just built
98       */
99      protected static ValidationResponse success(final String type) {
100         final DefaultValidationResponse resp = new DefaultValidationResponse(
101             true,
102             URI.create("http://localhost/success"),
103             type,
104             Charset.defaultCharset()
105         );
106         return resp;
107     }
108 
109     /**
110      * Get text from list of strings, returned by
111      * {@link XML#xpath(String)}.
112      *
113      * <p>This method is required to simplify manipulations with XPath returned
114      * list of strings (returned by {@link XML#xpath(String)} above).
115      * The list of strings normally (!) contains one element or no elements. If
116      * there are no elements it means that the XPath is not found in the
117      * document. In this case we should return an empty string. If any elements
118      * are found - we're interested only in the first one. All others are
119      * ignored, because simply should not exist (if our XPath query is correct).
120      *
121      * @param lines The lines to work with
122      * @return The value
123      * @see #intOf(List)
124      */
125     protected static String textOf(final List<String> lines) {
126         final String text;
127         if (lines.isEmpty()) {
128             text = "";
129         } else {
130             text = lines.get(0);
131         }
132         return text;
133     }
134 
135     /**
136      * Get text from list of strings.
137      *
138      * <p>See explanation of {@link #textOf(List)}.
139      *
140      * @param lines The lines to work with
141      * @return The value
142      * @see #textOf(List)
143      */
144     protected static int intOf(final List<String> lines) {
145         final int value;
146         if (lines.isEmpty()) {
147             value = 0;
148         } else {
149             value = Integer.parseInt(lines.get(0));
150         }
151         return value;
152     }
153 
154     /**
155      * Convert text to charset.
156      * @param text Text representation of charset
157      * @return The charset
158      */
159     protected static Charset charset(final String text) {
160         final Charset charset;
161         if (text.isEmpty()) {
162             charset = Charset.defaultCharset();
163         } else {
164             charset = Charset.forName(text);
165         }
166         return charset;
167     }
168 
169 }