/*
* 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.zeppelin.markdown;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.support.StringBuilderVar;
import org.pegdown.Parser;
import org.pegdown.ast.ExpImageNode;
import org.pegdown.ast.TextNode;
import org.pegdown.plugins.BlockPluginParser;
import org.pegdown.plugins.PegDownPlugins;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* Pegdown plugin for Websequence diagram
*/
public class PegdownWebSequencelPlugin extends Parser implements BlockPluginParser {
private static final String WEBSEQ_URL = "http://www.websequencediagrams.com";
public PegdownWebSequencelPlugin() {
super(PegdownParser.OPTIONS,
PegdownParser.PARSING_TIMEOUT_AS_MILLIS,
DefaultParseRunnerProvider);
}
public PegdownWebSequencelPlugin(Integer opts, Long millis, ParseRunnerProvider provider,
PegDownPlugins plugins) {
super(opts, millis, provider, plugins);
}
public static final String TAG = "%%%";
Rule StartMarker() {
return Sequence(Spn1(), TAG, Sp(), "sequence", Sp());
}
String EndMarker() {
return TAG;
}
Rule Body() {
return OneOrMore(TestNot(TAG), BaseParser.ANY);
}
Rule BlockRule() {
StringBuilderVar style = new StringBuilderVar();
StringBuilderVar body = new StringBuilderVar();
return NodeSequence(
StartMarker(),
Optional(
String("style="),
Sequence(OneOrMore(Letter()), style.append(match()), Spn1())),
Sequence(Body(), body.append(match())),
EndMarker(),
push(
new ExpImageNode("title",
createWebsequenceUrl(style.getString(), body.getString()),
new TextNode("")))
);
}
public static String createWebsequenceUrl(String style,
String content) {
style = StringUtils.defaultString(style, "default");
OutputStreamWriter writer = null;
BufferedReader reader = null;
String webSeqUrl = "";
try {
String query = new StringBuilder()
.append("style=")
.append(style)
.append("&message=")
.append(URLEncoder.encode(content, "UTF-8"))
.append("&apiVersion=1")
.toString();
URL url = new URL(WEBSEQ_URL);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
writer = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
writer.write(query);
writer.flush();
StringBuilder response = new StringBuilder();
reader = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
writer.close();
reader.close();
String json = response.toString();
int start = json.indexOf("?png=");
int end = json.indexOf("\"", start);
if (start != -1 && end != -1) {
webSeqUrl = WEBSEQ_URL + "/" + json.substring(start, end);
}
} catch (IOException e) {
throw new RuntimeException("Failed to get proper response from websequencediagrams.com", e);
} finally {
IOUtils.closeQuietly(writer);
IOUtils.closeQuietly(reader);
}
return webSeqUrl;
}
@Override
public Rule[] blockPluginRules() {
return new Rule[]{BlockRule()};
}
}