org.opencastproject.util.doc.DocUtil Maven / Gradle / Ivy
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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.opencastproject.util.doc;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* This provides methods for handling documentation generation The is mainly for generating REST documentation but it
* could be used for other things as well
*
* @see DocData
*/
public final class DocUtil {
private static final Logger logger = LoggerFactory.getLogger(DocUtil.class);
private static Configuration freemarkerConfig; // reusable template processor
static {
// initialize the freemarker template engine
reset();
}
/** Disable construction of this utility class */
private DocUtil() {
}
public static void reset() {
freemarkerConfig = null;
// static initializer
freemarkerConfig = new Configuration();
freemarkerConfig.setObjectWrapper(new DefaultObjectWrapper());
freemarkerConfig.clearTemplateCache();
logger.debug("Created new freemarker template processor for DocUtils");
}
/**
* Handles the replacement of the variable strings within textual templates and also allows the setting of variables
* for the control of logical branching within the text template as well
* Uses and expects freemarker (http://freemarker.org/) style templates (that is using ${name} as the marker for a
* replacement)
* NOTE: These should be compatible with Velocity (http://velocity.apache.org/) templates if you use the formal
* notation (formal: ${variable}, shorthand: $variable)
*
* @param templateName
* this is the key to cache the template under
* @param textTemplate
* a freemarker/velocity style text template, cannot be null or empty string
* @param data
* a set of replacement values which are in the map like so:
* key => value (String => Object)
* "username" => "aaronz"
* @return the processed template
*/
public static String processTextTemplate(String templateName, String textTemplate, Map data) {
if (freemarkerConfig == null) {
throw new IllegalStateException("freemarkerConfig is not initialized");
}
if (StringUtils.isEmpty(templateName)) {
throw new IllegalArgumentException("The templateName cannot be null or empty string, "
+ "please specify a key name to use when processing this template (can be anything moderately unique)");
}
if (data == null || data.size() == 0) {
return textTemplate;
}
if (StringUtils.isEmpty(textTemplate)) {
throw new IllegalArgumentException("The textTemplate cannot be null or empty string, "
+ "please pass in at least something in the template or do not call this method");
}
// get the template
Template template;
try {
template = new Template(templateName, new StringReader(textTemplate), freemarkerConfig);
} catch (ParseException e) {
String msg = "Failure while parsing the Doc template (" + templateName + "), template is invalid: " + e
+ " :: template=" + textTemplate;
logger.error(msg);
throw new RuntimeException(msg, e);
} catch (IOException e) {
throw new RuntimeException("Failure while creating freemarker template", e);
}
// process the template
String result;
try {
Writer output = new StringWriter();
template.process(data, output);
result = output.toString();
logger.debug("Generated complete document ({} chars) from template ({})", result.length(), templateName);
} catch (TemplateException e) {
logger.error("Failed while processing the Doc template ({}): {}", templateName, e);
result = "ERROR:: Failed while processing the template (" + templateName + "): " + e + "\n Template: "
+ textTemplate + "\n Data: " + data;
} catch (IOException e) {
throw new RuntimeException("Failure while sending freemarker output to stream", e);
}
return result;
}
/**
* Use this method to generate the documentation using passed in document data, allows the user to specify the
* template that is used
*
* @param data
* any populated DocData object
* @param template
* any freemarker template which works with the DocData data structure
* @return the documentation (e.g. REST html) as a string
* @throws IllegalArgumentException
* if the input data is invalid in some way
* @see DocData
*/
public static String generate(DocData data, String template) {
if (template == null) {
throw new IllegalArgumentException("template must be set");
}
return processTextTemplate(data.getMetaData("name"), template, data.toMap());
}
/**
* Loads a template based on the given path
*
* @param path
* the path to load the template from (uses the current classloader)
* @return the template as a string
*/
public static String loadTemplate(String path) {
String textTemplate;
InputStream in = null;
try {
in = DocUtil.class.getResourceAsStream(path);
if (in == null) {
throw new NullPointerException("No template file could be found at: " + path);
}
textTemplate = new String(IOUtils.toByteArray(in));
} catch (Exception e) {
logger.error("failed to load template file from path (" + path + "): " + e, e);
textTemplate = null;
} finally {
IOUtils.closeQuietly(in);
}
return textTemplate;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy