package com.epam.wilma.stubconfig.dom.parser.node;
/*==========================================================================
Copyright 2013-2017 EPAM Systems
This file is part of Wilma.
Wilma is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Wilma is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wilma. If not, see <http://www.gnu.org/licenses/>.
===========================================================================*/
import com.epam.wilma.domain.stubconfig.dialog.response.ResponseDescriptor;
import com.epam.wilma.domain.stubconfig.dialog.response.ResponseDescriptorAttributes;
import com.epam.wilma.domain.stubconfig.dialog.response.template.Template;
import com.epam.wilma.domain.stubconfig.dialog.response.template.TemplateFormatterDescriptor;
import com.epam.wilma.domain.stubconfig.dialog.response.template.TemplateGenerator;
import com.epam.wilma.domain.stubconfig.dialog.response.template.TemplateType;
import com.epam.wilma.sequence.helper.SequenceDescriptorKeyUtil;
import com.epam.wilma.stubconfig.dom.parser.NodeParser;
import com.epam.wilma.stubconfig.dom.parser.node.helper.StubConfigXPathEvaluator;
import com.epam.wilma.domain.stubconfig.exception.DescriptorCannotBeParsedException;
import com.epam.wilma.stubconfig.initializer.template.TemplateFileReader;
import com.epam.wilma.stubconfig.initializer.template.TemplateGeneratorInitializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.nio.charset.StandardCharsets;
import java.util.Set;
/**
* Builds a new {@link ResponseDescriptor} from a DOM node.
*
* @author Tunde_Kovacs
*/
@Component
public class ResponseDescriptorParser implements NodeParser<ResponseDescriptor> {
@Autowired
private StubConfigXPathEvaluator xPathEvaluator;
@Autowired
@Qualifier("templateDescriptorParser")
private NodeParser<Set<TemplateFormatterDescriptor>> templateDescriptorParser;
@Autowired
private TemplateFileReader templateFileReader;
@Autowired
private TemplateGeneratorInitializer templateGeneratorInitializer;
@Autowired
private SequenceDescriptorKeyUtil sequenceDescriptorKeyUtil;
/**
* Builds a new {@link ResponseDescriptor} from a DOM node.
*
* @param responseDescriptorNode the response descriptor node that is parsed
* @param document the DOM document that is parsed, needed to be able to find nodes outside
* the <tt>responseDescriptorNode</tt>
* @return a new {@link ResponseDescriptor}. If input parameter <tt>responseDescriptorNode</tt>
* is null, it returns null.
*/
@Override
public ResponseDescriptor parseNode(final Node responseDescriptorNode, final Document document) {
ResponseDescriptor responseDescriptor = null;
if (responseDescriptorNode != null) {
Element el = (Element) responseDescriptorNode;
ResponseDescriptorAttributes attributes = getAttributes(el, document);
Set<TemplateFormatterDescriptor> templateFormatters = templateDescriptorParser.parseNode(el, document);
responseDescriptor = new ResponseDescriptor(attributes, templateFormatters);
}
return responseDescriptor;
}
private ResponseDescriptorAttributes getAttributes(final Element el, final Document document) {
int delay = Integer.valueOf(el.getAttribute("delay"));
String code = el.getAttribute("code");
String mimeType = el.getAttribute("mimetype");
Template template = getTemplate(el.getAttribute("template"), document);
String groupname = document.getDocumentElement().getAttribute("groupname");
String sequenceDescriptorName = el.getAttribute("sequenceDescriptorName");
String sequenceDescriptorKey = sequenceDescriptorKeyUtil.createDescriptorKey(groupname, sequenceDescriptorName);
ResponseDescriptorAttributes responseDescriptorAttributes = new ResponseDescriptorAttributes.Builder().delay(delay).code(code)
.mimeType(mimeType).template(template).sequenceDescriptorKey(sequenceDescriptorKey).build();
return responseDescriptorAttributes;
}
private Template getTemplate(final String templateName, final Document document) {
Element element = xPathEvaluator.getElementByXPath(
"/wilma:wilma-stub/wilma:template-descriptor/wilma:template[@name='" + templateName + "']", document);
TemplateType templateType = getTemplateType(element.getAttribute("type"));
String resourceName = element.getAttribute("resource");
byte[] resource = initializeResource(templateType, resourceName);
return new Template(templateName, templateType, resource);
}
private byte[] initializeResource(final TemplateType templateType, final String resource) {
byte[] result;
if (templateType == TemplateType.HTML || templateType == TemplateType.TEXT || templateType == TemplateType.XML) {
result = resource.getBytes(StandardCharsets.UTF_8);
} else if (templateType == TemplateType.EXTERNAL) {
result = getTemplateFromTemplateGenerator(resource);
} else {
result = templateFileReader.readTemplate(resource);
}
return result;
}
/**
* Loads external template formatter class.
*
* @param resource is the template generator class resource name
* @return with the template, generated by the template generator class
*/
private byte[] getTemplateFromTemplateGenerator(final String resource) {
byte[] result;
TemplateGenerator templateGenerator = templateGeneratorInitializer.getTemplateGenerator(resource);
try {
result = templateGenerator.generateTemplate();
} catch (Exception e) {
throw new DescriptorCannotBeParsedException("Descriptor can not be validated, because template generation failed at: "
+ templateGenerator.getClass().getName() + ": " + e.getMessage(), e);
}
return result;
}
private TemplateType getTemplateType(final String type) {
return TemplateType.valueOf(type.toUpperCase());
}
}