package fi.otavanopisto.muikku.plugins.dnm;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathExpressionException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.xerces.parsers.DOMParser;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.cyberneko.html.HTMLConfiguration;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import fi.otavanopisto.muikku.controller.PluginSettingsController;
import fi.otavanopisto.muikku.model.workspace.WorkspaceEntity;
import fi.otavanopisto.muikku.plugins.dnm.parser.DeusNexException;
import fi.otavanopisto.muikku.plugins.dnm.parser.DeusNexInternalException;
import fi.otavanopisto.muikku.plugins.dnm.parser.DeusNexXmlUtils;
import fi.otavanopisto.muikku.plugins.dnm.parser.content.DeusNexContentParser;
import fi.otavanopisto.muikku.plugins.dnm.parser.content.DeusNexEmbeddedItemElementHandler;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.DeusNexDocument;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.DeusNexStructureParser;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Binary;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Document;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Folder;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Query;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Resource;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.ResourceContainer;
import fi.otavanopisto.muikku.plugins.dnm.parser.structure.model.Type;
import fi.otavanopisto.muikku.plugins.dnm.unembed.MaterialUnEmbedder;
import fi.otavanopisto.muikku.plugins.material.BinaryMaterialController;
import fi.otavanopisto.muikku.plugins.material.HtmlMaterialController;
import fi.otavanopisto.muikku.plugins.material.model.BinaryMaterial;
import fi.otavanopisto.muikku.plugins.material.model.HtmlMaterial;
import fi.otavanopisto.muikku.plugins.material.model.Material;
import fi.otavanopisto.muikku.plugins.workspace.WorkspaceMaterialController;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceFolder;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterial;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialAssignmentType;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceMaterialCorrectAnswersDisplay;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceNode;
import fi.otavanopisto.muikku.plugins.workspace.model.WorkspaceNodeType;
@ApplicationScoped
@Stateful
public class DeusNexMachinaController {
@Inject
private Logger logger;
@Inject
private PluginSettingsController pluginSettingsController;
@Inject
private MaterialUnEmbedder materialUnEmbedder;
private class EmbeddedItemHandler implements DeusNexEmbeddedItemElementHandler {
public EmbeddedItemHandler(DeusNexMachinaController deusNexMachinaController, WorkspaceNode importRoot, DeusNexDocument deusNexDocument) {
this.importRoot = importRoot;
this.deusNexDocument = deusNexDocument;
}
@Override
public Node handleEmbeddedDocument(org.w3c.dom.Document ownerDocument, String title, Integer queryType, Integer resourceNo,
Integer embeddedResourceNo) {
// TODO: This is just for show, real implementation depends on HtmlMaterial implementation
String relativePath = getResourcePath(resourceNo);
if (relativePath != null) {
Element iframeElement = ownerDocument.createElement("iframe");
iframeElement.setAttribute("src", relativePath);
iframeElement.setAttribute("title", title);
iframeElement.setAttribute("seamless", "seamless");
iframeElement.setAttribute("border", "0");
iframeElement.setAttribute("frameborder", "0");
if (queryType != null && queryType.intValue() == 1) {
iframeElement.setAttribute("data-assignment-type", "EXERCISE");
}
if (queryType != null && queryType.intValue() == 2) {
iframeElement.setAttribute("data-assignment-type", "EVALUATED");
}
iframeElement.setAttribute("data-type", "embedded-document");
iframeElement.setAttribute("data-resource-no", String.valueOf(resourceNo));
iframeElement.setAttribute("width", "100%");
iframeElement.setTextContent("Browser does not support iframes");
return iframeElement;
} else {
logger.warning("Embedded document " + resourceNo + " could not be found.");
}
return null;
}
@Override
public Node handleEmbeddedImage(org.w3c.dom.Document ownerDocument, String title, String alt, Integer width, Integer height,
Integer hspace, String align, Integer resourceNo) {
String relativePath = getResourcePath(resourceNo);
if (relativePath != null) {
Element imgElement = ownerDocument.createElement("img");
imgElement.setAttribute("src", relativePath);
imgElement.setAttribute("title", title);
imgElement.setAttribute("alt", alt);
imgElement.setAttribute("width", String.valueOf(width));
imgElement.setAttribute("height", String.valueOf(height));
imgElement.setAttribute("hspace", String.valueOf(hspace));
imgElement.setAttribute("align", align);
return imgElement;
} else {
logger.warning("Embedded image " + resourceNo + " could not be found.");
}
return null;
}
@Override
public Node handleEmbeddedAudio(org.w3c.dom.Document ownerDocument, Integer resourceNo, Boolean showAsLink, String fileName,
String linkText, Boolean autoStart, Boolean loop) {
String path = getResourcePath(resourceNo);
if (path != null) {
if (showAsLink) {
Element linkElement = ownerDocument.createElement("a");
linkElement.setTextContent(linkText);
linkElement.setAttribute("target", "_blank");
linkElement.setAttribute("href", path);
return linkElement;
} else {
Element audioElement = ownerDocument.createElement("audio");
String contentType = getResorceContentType(resourceNo);
if (StringUtils.isNotBlank(contentType)) {
Element sourceElement = ownerDocument.createElement("source");
sourceElement.setAttribute("src", path + "?embed=true");
sourceElement.setAttribute("type", contentType);
audioElement.appendChild(sourceElement);
} else {
logger.warning("Embedded audio " + resourceNo + " content type could not be resolved.");
}
if (autoStart) {
audioElement.setAttribute("autoplay", "autoplay");
}
if (loop) {
audioElement.setAttribute("loop", "loop");
}
return audioElement;
}
} else {
logger.warning("Embedded audio " + resourceNo + " could not be found.");
}
return null;
}
@Override
public Node handleEmbeddedHyperlink(org.w3c.dom.Document ownerDocument, Integer resourceNo, String target, String fileName,
String linkText) {
String path = getResourcePath(resourceNo);
if (path != null) {
Element hyperLinkElement = ownerDocument.createElement("a");
hyperLinkElement.setAttribute("href", path);
if (StringUtils.isNotBlank(target)) {
hyperLinkElement.setAttribute("target", target);
}
hyperLinkElement.setTextContent(linkText);
return hyperLinkElement;
} else {
logger.warning("Embedded hyperlink " + resourceNo + " could not be found.");
}
return null;
}
@Override
public Node handleEmbedded(org.w3c.dom.Document ownerDocument, Integer resRef, Boolean functionalRef, Boolean visible, Boolean autoStart, Integer width,
Integer height, Boolean showAsLink, Boolean showControls, Boolean loop, Integer queryType) {
Resource originalResource = deusNexDocument.getResourceByNo(resRef);
if (originalResource != null) {
switch (originalResource.getType()) {
case BINARY:
String contentType = getResorceContentType(resRef);
if (StringUtils.startsWith(contentType, "audio")) {
return handleEmbeddedAudio(ownerDocument, resRef, showAsLink, originalResource.getName(), originalResource.getTitle(), autoStart, loop);
} else if (StringUtils.startsWith(contentType, "image")) {
return handleEmbeddedImage(ownerDocument, originalResource.getTitle(), null, width, height, 0, null, resRef);
} else {
return handleEmbeddedHyperlink(ownerDocument, resRef, null, originalResource.getName(), originalResource.getTitle());
}
case DOCUMENT:
return handleEmbeddedDocument(ownerDocument, originalResource.getTitle(), queryType, resRef, null);
case FOLDER:
logger.warning(String.format("ix:embeded (%d) references into a folder, skpping", resRef));
break;
case QUERY:
return handleEmbeddedDocument(ownerDocument, originalResource.getTitle(), queryType, resRef, null);
}
} else {
Long workspaceNodeId = getResourceWorkspaceNodeId(resRef);
if (workspaceNodeId != null) {
WorkspaceMaterial workspaceMaterial = workspaceMaterialController.findWorkspaceMaterialById(workspaceNodeId);
if (workspaceMaterial != null) {
Material material = workspaceMaterialController.getMaterialForWorkspaceMaterial(workspaceMaterial);
if (material instanceof BinaryMaterial) {
BinaryMaterial binaryMaterial = ((BinaryMaterial) material);
String contentType = binaryMaterial.getContentType();
if (StringUtils.startsWith(contentType, "audio")) {
return handleEmbeddedAudio(ownerDocument, resRef, showAsLink, workspaceMaterial.getUrlName(), material.getTitle(), autoStart, loop);
} else if (StringUtils.startsWith(contentType, "image")) {
return handleEmbeddedImage(ownerDocument, material.getTitle(), null, width, height, 0, null, resRef);
} else {
return handleEmbeddedHyperlink(ownerDocument, resRef, null, workspaceMaterial.getUrlName(), material.getTitle());
}
} else if (material instanceof HtmlMaterial) {
HtmlMaterial htmlMaterial = ((HtmlMaterial) material);
return handleEmbeddedDocument(ownerDocument, htmlMaterial.getTitle(), queryType, resRef, null);
}
} else {
logger.warning(String.format("Could not find workspace material for ix:embeded (%d)", resRef));
}
} else {
logger.warning(String.format("Could not find node id for ix:embeded (%d)", resRef));
}
}
return null;
}
private String getResourcePath(Integer resourceNo) {
String path = null;
String type = null;
Long workspaceNodeId = getResourceWorkspaceNodeId(resourceNo);
if (workspaceNodeId != null) {
// Resource has been imported before
WorkspaceMaterial workspaceMaterial = workspaceMaterialController.findWorkspaceMaterialById(workspaceNodeId);
if (workspaceMaterial != null) {
path = "/" + workspaceMaterialController.getCompletePath(workspaceMaterial);
type = "POOL";
}
} else {
Resource resource = deusNexDocument.getResourceByNo(resourceNo);
if (resource != null) {
WorkspaceNode reference = importRoot.getParent();
if (reference == null) {
reference = importRoot;
}
String rootPath = workspaceMaterialController.getCompletePath(reference);
if (!rootPath.endsWith("/")) {
rootPath += '/';
}
String resourcePath = getResourcePath(deusNexDocument, resource);
path = "/" + rootPath + resourcePath;
type = "DND";
}
}
if (path != null) {
path += "?embed=true&on=" + resourceNo + "&rt=" + type;
}
return path;
}
private String getResourcePath(DeusNexDocument deusNexDocument, Resource resource) {
List<String> result = new ArrayList<String>();
ResourceContainer parent = deusNexDocument.getParent(resource);
do {
result.add(0, parent.getName());
parent = deusNexDocument.getParent(parent);
} while (parent != null);
result.add(resource.getName());
if ((!result.isEmpty()) && (StringUtils.equals("materiaalit", result.get(0)))) {
result.remove(0);
}
return StringUtils.join(result, '/');
}
private String getResorceContentType(Integer resourceNo) {
Resource resource = deusNexDocument.getResourceByNo(resourceNo);
if (resource != null) {
if (resource instanceof Binary) {
return ((Binary) resource).getContentType();
}
}
Long workspaceNodeId = getResourceWorkspaceNodeId(resourceNo);
if (workspaceNodeId != null) {
// TODO: This reference is a bit strange
WorkspaceMaterial workspaceMaterial = workspaceMaterialController.findWorkspaceMaterialById(workspaceNodeId);
if (workspaceMaterial != null) {
Material material = workspaceMaterialController.getMaterialForWorkspaceMaterial(workspaceMaterial);
if (material instanceof BinaryMaterial) {
return ((BinaryMaterial) material).getContentType();
}
}
}
return null;
}
private WorkspaceNode importRoot;
private DeusNexDocument deusNexDocument;
}
private final static String LOOKUP_SETTING_NAME = "[_DEUS_NEX_MACHINA_LOOKUP_]";
private final static String IDS_SETTING_NAME = "[_DEUS_NEX_MACHINA_IDS_]";
@Inject
private HtmlMaterialController htmlMaterialController;
@Inject
private BinaryMaterialController binaryMaterialController;
@Inject
private WorkspaceMaterialController workspaceMaterialController;
@PostConstruct
public void init() throws IOException {
deusNexStructureParser = new DeusNexStructureParser();
loadLookup();
loadIdMap();
}
public DeusNexDocument parseDeusNexDocument(InputStream inputStream) throws DeusNexException {
return deusNexStructureParser.parseDocument(inputStream);
}
public void importDeusNexDocument(WorkspaceNode parentNode, InputStream inputStream) throws DeusNexException {
DeusNexDocument desNexDocument = parseDeusNexDocument(inputStream);
List<WorkspaceNode> createdNodes = new ArrayList<>();
for (Resource resource : desNexDocument.getRootFolder().getResources()) {
importResource(parentNode, parentNode, resource, desNexDocument, createdNodes);
}
try {
postProcessResources(createdNodes);
} catch (Exception e) {
throw new DeusNexInternalException("PostProcesssing failed. ", e);
}
materialUnEmbedder.unembedWorkspaceMaterials(parentNode);
}
public void importFrontPageDocument(WorkspaceEntity workspaceEntity, InputStream inputStream) throws DeusNexException {
DeusNexDocument deusNexDocument = parseDeusNexDocument(inputStream);
List<Resource> resources = deusNexDocument.getRootFolder().getResources();
if (!resources.isEmpty()) {
List<WorkspaceNode> createdNodes = new ArrayList<>();
WorkspaceFolder workspaceFrontPageFolder = workspaceMaterialController.createWorkspaceFrontPageFolder(workspaceEntity);
for (Resource resource : deusNexDocument.getRootFolder().getResources()) {
importResource(workspaceFrontPageFolder, workspaceFrontPageFolder, resource, deusNexDocument, createdNodes);
}
try {
postProcessResources(createdNodes);
} catch (Exception e) {
throw new DeusNexInternalException("PostProcesssing failed. ", e);
}
}
}
public void importHelpPageDocument(WorkspaceEntity workspaceEntity, InputStream inputStream) throws DeusNexException {
DeusNexDocument deusNexDocument = parseDeusNexDocument(inputStream);
List<Resource> resources = deusNexDocument.getRootFolder().getResources();
if (!resources.isEmpty()) {
List<WorkspaceNode> createdNodes = new ArrayList<>();
WorkspaceFolder workspaceHelpPageFolder = workspaceMaterialController.createWorkspaceHelpPageFolder(workspaceEntity);
for (Resource resource : deusNexDocument.getRootFolder().getResources()) {
importResource(workspaceHelpPageFolder, workspaceHelpPageFolder, resource, deusNexDocument, createdNodes);
}
try {
postProcessResources(createdNodes);
} catch (Exception e) {
throw new DeusNexInternalException("PostProcesssing failed. ", e);
}
}
}
private void postProcessResources(List<WorkspaceNode> createdNodes) throws ParserConfigurationException, SAXException, IOException,
XPathExpressionException, TransformerException {
for (WorkspaceNode node : createdNodes) {
if (node.getType() == WorkspaceNodeType.MATERIAL) {
WorkspaceMaterial workspaceMaterial = (WorkspaceMaterial) node;
HtmlMaterial htmlMaterial = htmlMaterialController.findHtmlMaterialById(workspaceMaterial.getMaterialId());
if (htmlMaterial != null && StringUtils.isNotBlank(htmlMaterial.getHtml())) {
postProcessHtml(htmlMaterial);
}
}
}
}
private void postProcessHtml(HtmlMaterial material) throws ParserConfigurationException, SAXException, IOException,
XPathExpressionException, TransformerException {
StringReader htmlReader = new StringReader(material.getHtml());
DOMParser parser = new DOMParser(new HTMLConfiguration());
parser.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
InputSource inputSource = new InputSource(htmlReader);
parser.parse(inputSource);
org.w3c.dom.Document domDocument = parser.getDocument();
boolean modified = false;
// Embedded YouTube clips; strip protocol
List<Element> elements = DeusNexXmlUtils.getElementsByXPath(domDocument.getDocumentElement(), "//iframe");
if (!elements.isEmpty()) {
for (Element element : elements) {
String src = element.getAttribute("src");
if (src != null && src.startsWith("http://www.youtube.com/")) {
element.setAttribute("src", src.substring(5));
modified = true;
}
}
}
// Embedded documents; add data attributes and determine correct material title
elements = DeusNexXmlUtils.getElementsByXPath(domDocument.getDocumentElement(), "//iframe[@data-type=\"embedded-document\"]");
if (!elements.isEmpty()) {
modified = true;
for (Element element : elements) {
Integer resourceNo = Integer.valueOf(element.getAttribute("data-resource-no"));
WorkspaceMaterial workspaceMaterial = workspaceMaterialController.findWorkspaceMaterialById(getResourceWorkspaceNodeId(resourceNo));
HtmlMaterial htmlMaterial = htmlMaterialController.findHtmlMaterialById(workspaceMaterial.getMaterialId());
// If a header precedes an embedded document, use its text as the embedded
// document's title and remove it from the parent document altogether
Node possibleHeaderNode = getPreviousSiblingElement(element);
if (isHeader(possibleHeaderNode)) {
String headerText = StringUtils.trim(possibleHeaderNode.getTextContent());
if (!StringUtils.isBlank(headerText)) {
htmlMaterialController.updateHtmlMaterialTitle(htmlMaterial, headerText);
possibleHeaderNode.getParentNode().removeChild(possibleHeaderNode);
}
}
element.setAttribute("data-material-id", String.valueOf(htmlMaterial.getId()));
element.setAttribute("data-material-type", htmlMaterial.getType());
element.setAttribute("data-workspace-material-id", String.valueOf(workspaceMaterial.getId()));
}
}
// Update to post-processed version, if applicable
if (modified) {
StringWriter writer = new StringWriter();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.transform(new DOMSource(domDocument), new StreamResult(writer));
htmlMaterialController.updateHtmlMaterialHtml(material, writer.getBuffer().toString());
}
}
private Node getPreviousSiblingElement(Node node) {
Node n = node == null ? null : node.getPreviousSibling();
while (n != null && !(n instanceof Element)) {
n = n.getPreviousSibling();
}
return n;
}
private boolean isHeader(Node node) {
return node instanceof Element && stringIn(((Element) node).getTagName(), new String[] { "h1", "h2", "h3", "h4", "h5", "h6" });
}
private boolean stringIn(String value, String[] values) {
for (int i = 0; i < values.length; i++) {
if (value.equals(values[i])) {
return true;
}
}
return false;
}
private WorkspaceMaterialAssignmentType determineEmbeddedAssignmentType(HtmlMaterial material) throws DeusNexException {
try {
if (material.getHtml() == null) {
return null;
}
StringReader htmlReader = new StringReader(material.getHtml());
DOMParser parser = new DOMParser();
InputSource inputSource = new InputSource(htmlReader);
parser.parse(inputSource);
org.w3c.dom.Document domDocument = parser.getDocument();
List<Element> elements = DeusNexXmlUtils.getElementsByXPath(domDocument.getDocumentElement(),
"//iframe[@data-type=\"embedded-document\"]");
List<WorkspaceMaterialAssignmentType> assignmentTypes = new ArrayList<>();
if (!elements.isEmpty()) {
for (Element element : elements) {
if ("EXERCISE".equals(element.getAttribute("data-assignment-type"))) {
assignmentTypes.add(WorkspaceMaterialAssignmentType.EXERCISE);
}
if ("EVALUATED".equals(element.getAttribute("data-assignment-type"))) {
assignmentTypes.add(WorkspaceMaterialAssignmentType.EVALUATED);
}
}
}
if (assignmentTypes.isEmpty()
|| (assignmentTypes.contains(WorkspaceMaterialAssignmentType.EXERCISE) && assignmentTypes
.contains(WorkspaceMaterialAssignmentType.EVALUATED))) {
return null;
} else {
return assignmentTypes.get(0);
}
} catch (SAXException | IOException | XPathExpressionException e) {
throw new DeusNexInternalException("Embedded assignment type handling failed. ", e);
}
}
private void importResource(WorkspaceNode importRoot, WorkspaceNode parent, Resource resource, DeusNexDocument deusNexDocument,
List<WorkspaceNode> createdNodes) throws DeusNexException {
WorkspaceNode node = findNode(parent, resource);
if (resource.getType() == Type.FOLDER) {
Folder folderResource = (Folder) resource;
WorkspaceFolder folder = null;
if (node instanceof WorkspaceFolder) {
folder = (WorkspaceFolder) node;
}
if (folder == null) {
folder = createFolder(parent, folderResource);
try {
setResourceWorkspaceNodeId(resource.getNo(), folder.getId());
} catch (IOException e) {
throw new DeusNexInternalException("Failed to store resourceNo lookup file", e);
}
createdNodes.add(folder);
}
for (Resource childResource : folderResource.getResources()) {
importResource(importRoot, folder, childResource, deusNexDocument, createdNodes);
}
} else {
if (node == null) {
logger.fine("importing " + resource.getPath());
Material material = createMaterial(importRoot, resource, deusNexDocument);
if (material != null) {
WorkspaceMaterialAssignmentType assignmentType = null;
if (resource instanceof Query) {
switch (((Query) resource).getQueryType()) {
case "1":
assignmentType = WorkspaceMaterialAssignmentType.EXERCISE;
break;
case "2":
assignmentType = WorkspaceMaterialAssignmentType.EVALUATED;
break;
}
} else if (material instanceof HtmlMaterial) {
assignmentType = determineEmbeddedAssignmentType((HtmlMaterial) material);
}
WorkspaceMaterial workspaceMaterial = workspaceMaterialController.createWorkspaceMaterial(
parent, material, resource.getName(), assignmentType, WorkspaceMaterialCorrectAnswersDisplay.ALWAYS);
try {
setResourceWorkspaceNodeId(resource.getNo(), workspaceMaterial.getId());
} catch (IOException e) {
throw new DeusNexInternalException("Failed to store resourceNo lookup file", e);
}
if (resource instanceof ResourceContainer) {
List<Resource> childResources = ((ResourceContainer) resource).getResources();
if (childResources != null) {
for (Resource childResource : childResources) {
importResource(importRoot, workspaceMaterial, childResource, deusNexDocument, createdNodes);
}
}
}
if (resource.getHidden()) {
workspaceMaterialController.hideWorkspaceNode(workspaceMaterial);
}
createdNodes.add(workspaceMaterial);
}
} else {
logger.info(node.getPath() + " already exists, skipping");
}
}
}
private Material createMaterial(WorkspaceNode importRoot, Resource resource, DeusNexDocument deusNexDocument) throws DeusNexException {
switch (resource.getType()) {
case BINARY:
return createBinaryMaterial((Binary) resource);
case DOCUMENT:
return createDocumentMaterial(importRoot, (Document) resource, deusNexDocument);
case QUERY:
return createQueryMaterial(importRoot, (Query) resource, deusNexDocument);
default:
break;
}
return null;
}
private Material createDocumentMaterial(WorkspaceNode importRoot, Document resource, DeusNexDocument deusNexDocument)
throws DeusNexException {
String title = resource.getTitle();
String html = parseDocumentContent(importRoot, resource.getDocument(), deusNexDocument);
return htmlMaterialController.createHtmlMaterial(title, html, "text/html;editor=CKEditor", 0l, null);
}
private Material createQueryMaterial(WorkspaceNode importRoot, Query resource, DeusNexDocument deusNexDocument) throws DeusNexException {
// TODO: Replace with query implementation when the implementation itself is ready for it
String title = resource.getTitle();
String html = parseQueryContent(importRoot, resource.getDocument(), deusNexDocument);
return htmlMaterialController.createHtmlMaterial(title, html, "text/html;editor=CKEditor", 0l, null);
}
private BinaryMaterial createBinaryMaterial(Binary resource) {
String title = resource.getName(); // Nexus title is usually something like "tiedosto"
String contentType = resource.getContentType();
byte[] content = resource.getContent();
return binaryMaterialController.createBinaryMaterial(title, contentType, content, null);
}
private String parseDocumentContent(WorkspaceNode importRoot, Element document, DeusNexDocument deusNexDocument) throws DeusNexException {
Map<String, String> localeContents = new DeusNexContentParser().setEmbeddedItemElementHandler(
new EmbeddedItemHandler(this, importRoot, deusNexDocument)).parseContent(document);
String contentFi = localeContents.get("fi");
return contentFi;
}
private String parseQueryContent(WorkspaceNode importRoot, Element document, DeusNexDocument deusNexDocument) throws DeusNexException {
Map<String, String> localeContents = new DeusNexContentParser()
.setEmbeddedItemElementHandler(new EmbeddedItemHandler(this, importRoot, deusNexDocument))
.setFieldElementHandler(new FieldElementsHandler(deusNexDocument)).parseContent(document);
String contentFi = localeContents.get("fi");
return contentFi;
}
private WorkspaceFolder createFolder(WorkspaceNode parent, Folder resource) {
return workspaceMaterialController.createWorkspaceFolder(parent, resource.getTitle(), resource.getName());
}
private WorkspaceNode findNode(WorkspaceNode parent, Resource resource) {
return workspaceMaterialController.findWorkspaceNodeByParentAndUrlName(parent, resource.getName());
}
private void setResourceWorkspaceNodeId(Integer resourceNo, Long workspaceNodeId) throws IOException {
lookupProperties.put(String.valueOf(resourceNo), String.valueOf(workspaceNodeId));
storeLookup();
}
Long getResourceWorkspaceNodeId(Integer resourceNo) {
return NumberUtils.createLong(lookupProperties.getProperty(String.valueOf(resourceNo)));
}
private void loadLookup() throws IOException {
lookupProperties = new Properties();
String lookupSetting = pluginSettingsController.getPluginSetting(DeusNexMachinaPluginDescriptor.PLUGIN_NAME, LOOKUP_SETTING_NAME);
if (StringUtils.isNotBlank(lookupSetting)) {
StringReader lookupSettingReader = new StringReader(lookupSetting);
try {
lookupProperties.load(lookupSettingReader);
} finally {
lookupSettingReader.close();
}
}
}
private void storeLookup() throws IOException {
StringWriter lookupSettingWriter = new StringWriter();
lookupProperties.store(lookupSettingWriter, null);
String lookupSetting = lookupSettingWriter.toString();
pluginSettingsController.setPluginSetting(DeusNexMachinaPluginDescriptor.PLUGIN_NAME, LOOKUP_SETTING_NAME, lookupSetting);
}
public void setWorkspaceEntityIdDnmId(String dnmId, Long workspaceEntityId) throws IOException {
idMap.put(dnmId, workspaceEntityId);
storeIdMap();
}
public Long getWorkspaceEntityIdDnmId(String dnmId) {
return idMap.get(dnmId);
}
private void storeIdMap() throws IOException {
pluginSettingsController.setPluginSetting(DeusNexMachinaPluginDescriptor.PLUGIN_NAME, IDS_SETTING_NAME,
new ObjectMapper().writeValueAsString(idMap));
}
private void loadIdMap() throws IOException {
String setting = pluginSettingsController.getPluginSetting(DeusNexMachinaPluginDescriptor.PLUGIN_NAME, IDS_SETTING_NAME);
if (StringUtils.isNotBlank(setting)) {
idMap = new ObjectMapper().readValue(setting, new TypeReference<Map<String, Long>>() {
});
} else {
idMap = new HashMap<>();
}
}
private DeusNexStructureParser deusNexStructureParser;
private Properties lookupProperties;
private Map<String, Long> idMap;
}