| 11 января, понедельник, 2021 | 22:45:38

Скопировано в буфер обмена!  Копировать Боковая панель Переносы строк Сырой код
1package ru.exlmoto.code.controller;
2
3import com.fasterxml.jackson.core.JsonProcessingException;
4import com.fasterxml.jackson.databind.ObjectMapper;
5import com.fasterxml.jackson.databind.node.ObjectNode;
6
7import org.slf4j.Logger;
8import org.slf4j.LoggerFactory;
9
10import org.springframework.util.StringUtils;
11import org.springframework.web.bind.annotation.GetMapping;
12import org.springframework.web.bind.annotation.PathVariable;
13import org.springframework.web.bind.annotation.PostMapping;
14import org.springframework.web.bind.annotation.RestController;
15import org.springframework.web.bind.annotation.RequestParam;
16
17import ru.exlmoto.code.configuration.CodeConfiguration;
18import ru.exlmoto.code.controller.enumeration.Skin;
19import ru.exlmoto.code.entity.CodeEntity;
20import ru.exlmoto.code.helper.ResourceHelper;
21import ru.exlmoto.code.helper.UtilityHelper;
22import ru.exlmoto.code.highlight.HighlightService;
23import ru.exlmoto.code.highlight.enumeration.Mode;
24import ru.exlmoto.code.service.DatabaseService;
25
26import java.io.InputStream;
27import java.io.UncheckedIOException;
28
29import java.util.Scanner;
30
31@RestController
32public class ApiController {
33 private final Logger log = LoggerFactory.getLogger(ApiController.class);
34
35 private final CodeConfiguration config;
36 private final DatabaseService database;
37 private final HighlightService highlight;
38 private final ResourceHelper resource;
39 private final UtilityHelper util;
40
41 public ApiController(CodeConfiguration config,
42 DatabaseService database,
43 HighlightService highlight,
44 ResourceHelper resource,
45 UtilityHelper util) {
46 this.config = config;
47 this.database = database;
48 this.highlight = highlight;
49 this.resource = resource;
50 this.util = util;
51 }
52
53 @GetMapping(path = "/api/raw/{id}", produces = "text/plain;charset=UTF-8")
54 public String raw(@PathVariable(name = "id") String id) {
55 return util.getLong(id).flatMap(database::getCodeSnippet).map(CodeEntity::getCodeRaw).orElse(
56 "Error: Cannot get code snippet with '" + id + "' id."
57 );
58 }
59
60 /*
61 * Highlight API usage examples:
62 * $ cat file.txt | curl --data-binary @- "https://code.exlmoto.ru/api/"
63 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml"
64 * $ cat src.java | curl --data-binary @- "https://code.exlmoto.ru/api/?o=java"
65 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines"
66 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15"
67 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15,20"
68 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15,20&h=HighlightJs"
69 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15,20&h=HighlightRouge"
70 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15,20&h=HighlightPygments"
71 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml;nolines;15&h=HighlightPygmentsJython"
72 *
73 * Create simple HTML page:
74 * $ cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml" > page.html
75 * Another way:
76 * $ CONTENT=`cat file.xml | curl --data-binary @- "https://code.exlmoto.ru/api/?o=xml"`
77 * $ echo "<code class="hljs highlight"><pre>$CONTENT</pre></code>" > page.html
78 */
79 @PostMapping(path = "/api", produces = "text/plain;charset=UTF-8")
80 public String highlight(InputStream inputDataStream,
81 @RequestParam(name = "o", required = false, defaultValue = "") String options,
82 @RequestParam(name = "h", required = false, defaultValue = "HighlightJs") String mode) {
83 Scanner scanner = new Scanner(inputDataStream).useDelimiter("\\A"); // https://stackoverflow.com/a/5445161
84 if (scanner.hasNext()) {
85 String code = scanner.next();
86 if (StringUtils.hasText(code) && code.length() < config.getSnippetMaxLength()) {
87 return highlight.highlightCode(Mode.getMode(mode), util.getCorrectOptions(options), code);
88 }
89 }
90 scanner.close();
91 return "Error: Cannot highlight code snippet.";
92 }
93
94 /*
95 * Highlight CSS usage examples:
96 * $ curl "https://code.exlmoto.ru/api/css"
97 * $ curl "https://code.exlmoto.ru/api/css?skin=pastorg"
98 * $ curl "https://code.exlmoto.ru/api/css?skin=pastorg&mode=HighlightRouge"
99 * $ curl "https://code.exlmoto.ru/api/css?skin=techno&mode=HighlightPygments"
100 */
101 @GetMapping(path = "/api/css", produces = "text/css;charset=UTF-8")
102 public String css(@RequestParam(name = "skin", required = false, defaultValue = "techno") String skin,
103 @RequestParam(name = "mode", required = false, defaultValue = "HighlightJs") String mode) {
104 try {
105 return resource.readFileToString("classpath:" + Mode.getCss(Mode.valueOf(mode), Skin.valueOf(skin)));
106 } catch (IllegalArgumentException | UncheckedIOException ignored) { }
107 return "Error: Cannot get CSS from resources.";
108 }
109
110 @GetMapping(path = "/api/versions", produces = "application/json;charset=UTF-8")
111 public String versions() {
112 final ObjectMapper mapper = new ObjectMapper();
113 final ObjectNode root = mapper.createObjectNode();
114 highlight.getLibraryVersions().forEach((k, v) -> {
115 final ObjectNode child = mapper.createObjectNode();
116 child.put("language", v.getFirst());
117 child.put("library", v.getSecond());
118 root.set(k.name(), child);
119 });
120 root.put("GraalVM", highlight.getApplicationVersions().getFirst());
121 root.put("CodePolyglot", highlight.getApplicationVersions().getSecond());
122
123 try {
124 return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
125 } catch (JsonProcessingException jpe) {
126 final String error = String.format("Cannot generate JSON version information: '%s'.", jpe.getMessage());
127 log.error(error, jpe);
128 return "{ \"error\" : \"" + error + "\" }";
129 }
130 }
131}
```
Язык
Библиотека
VM
Скорость
JavaScript 20.3.0
Highlight.js 10.4.1
GraalVM
Быстро
Ruby 2.6.6
Rouge 3.26.0
GraalVM
Приемлемо
Время рендеринга подсветки синтаксиса на сервере: 1877ms.
```
Версия Code Polyglot: 1.0.0, 40b65db_190, 19-Jan-2021 15:55:44