package com.marklogic.client.modulesloader.impl;
import com.marklogic.client.admin.ExtensionMetadata;
import com.marklogic.client.admin.ExtensionMetadata.ScriptLanguage;
import com.marklogic.client.admin.MethodType;
import com.marklogic.client.admin.ResourceExtensionsManager.MethodParameters;
import com.marklogic.client.helper.FilenameUtil;
import com.marklogic.client.helper.LoggingObject;
import com.marklogic.client.modulesloader.ExtensionMetadataAndParams;
import com.marklogic.client.modulesloader.ExtensionMetadataProvider;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DefaultExtensionMetadataProvider extends LoggingObject implements ExtensionMetadataProvider {
private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
public ExtensionMetadataAndParams provideExtensionMetadataAndParams(Resource r) {
String filename = getFilenameMinusExtension(r);
URL url = null;
try {
url = r.getURL();
} catch (IOException ie) {
throw new RuntimeException(ie);
}
String metadataPath = url.toString().replace(r.getFilename(), "");
String metadataFile = metadataPath + "metadata/" + filename + ".xml";
ExtensionMetadata m = new ExtensionMetadata();
List<MethodParameters> paramList = new ArrayList<>();
if (FilenameUtil.isJavascriptFile(r.getFilename())) {
m.setScriptLanguage(ScriptLanguage.JAVASCRIPT);
m.setVersion("1.0");
}
Resource metadataResource = resolver.getResource(metadataFile);
if (metadataResource != null) {
try {
Element root = new SAXBuilder().build(metadataResource.getInputStream()).getRootElement();
m.setTitle(root.getChildText("title"));
Element desc = root.getChild("description");
if (desc.getChildren() != null && desc.getChildren().size() == 1) {
m.setDescription(new XMLOutputter().outputString(desc.getChildren().get(0)));
} else {
m.setDescription(desc.getText());
}
for (Element method : root.getChildren("method")) {
MethodParameters mp = new MethodParameters(MethodType.valueOf(method.getAttributeValue("name")));
paramList.add(mp);
for (Element param : method.getChildren("param")) {
String name = param.getAttributeValue("name");
String type = "xs:string";
if (param.getAttribute("type") != null) {
type = param.getAttributeValue("type");
}
mp.add(name, type);
}
}
} catch (IOException ie) {
// Log at debug level, this may just be due to the file missing
logger.debug("Unable to build metadata from resource file: " + url.toString() + "; cause: "
+ ie.getMessage());
setDefaults(m, r);
} catch (Exception e) {
logger.warn("Unable to build metadata from resource file: " + url.toString() + "; cause: "
+ e.getMessage());
setDefaults(m, r);
}
} else {
setDefaults(m, r);
}
return new ExtensionMetadataAndParams(m, paramList);
}
protected String getFilenameMinusExtension(Resource file) {
// Would think there's an easier way to do this in Java...
String[] tokens = file.getFilename().split("\\.");
tokens = Arrays.copyOfRange(tokens, 0, tokens.length - 1);
String filename = tokens[0];
for (int i = 1; i < tokens.length; i++) {
filename += "." + tokens[i];
}
return filename;
}
private void setDefaults(ExtensionMetadata metadata, Resource resourceFile) {
metadata.setTitle(getFilenameMinusExtension(resourceFile));
}
}