sdi-service/src/main/java/org/gcube/spatial/data/sdi/engine/impl/metadata/MetadataTemplateManagerImpl...

152 lines
5.4 KiB
Java

package org.gcube.spatial.data.sdi.engine.impl.metadata;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import javax.inject.Singleton;
import org.apache.commons.io.IOUtils;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.spatial.data.sdi.LocalConfiguration;
import org.gcube.spatial.data.sdi.engine.MetadataTemplateManager;
import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.AbstractTemplate;
import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.InvalidTemplateInvocationException;
import org.gcube.spatial.data.sdi.engine.impl.metadata.templates.ThreddsOnlineTemplate;
import org.gcube.spatial.data.sdi.model.metadata.MetadataReport;
import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor;
import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateNotFoundException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Singleton
public class MetadataTemplateManagerImpl implements MetadataTemplateManager {
private static Configuration cfg;
private static ArrayList<TemplateDescriptor> templateDescriptors=new ArrayList<>();
private static HashMap<String,AbstractTemplate> availableTemplates=new HashMap<>();
@Override
public void init(ApplicationContext ctx) {
// Create your Configuration instance, and specify if up to what FreeMarker
// version (here 2.3.25) do you want to apply the fixes that are not 100%
// backward-compatible. See the Configuration JavaDoc for details.
cfg = new Configuration(Configuration.VERSION_2_3_25);
// cfg.setDirectoryForTemplateLoading(TamplateManager.class.getPackage().new File("src/xmlTemplates"));
cfg.setServletContextForTemplateLoading(ctx, LocalConfiguration.get().getProperty(LocalConfiguration.METADATA_TEMPLATE_FOLDER));
// Set the preferred charset template files are stored in. UTF-8 is
// a good choice in most applications:
cfg.setDefaultEncoding("UTF-8");
// Sets how errors will appear.
// During web page *development* TemplateExceptionHandler.HTML_DEBUG_HANDLER is better.
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// Don't log exceptions inside FreeMarker that it will thrown at you anyway:
cfg.setLogTemplateExceptions(false);
// availableTemplates.add(new TemplateDescriptor("THREDDS-ONLINE", "Thredds online resources", "Template for online resources exposed by thredds.", "http://sdi-d4s.d4science.org"));
ThreddsOnlineTemplate tpl=new ThreddsOnlineTemplate();
availableTemplates.put(tpl.getDescriptor().getId(), tpl);
templateDescriptors.add(tpl.getDescriptor());
}
//
// public static String getTHREDDSLinks(ThreddsLinkRequest req) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException{
// Writer out=null;
// try{
// Template temp = cfg.getTemplate("OnlineResources.ftlx");
// ByteArrayOutputStream baos=new ByteArrayOutputStream();
// out=new OutputStreamWriter(baos);
// temp.process(req, out);
// out.flush();
// return baos.toString(StandardCharsets.UTF_8.toString());
// }finally{
// if(out!=null)
// IOUtils.closeQuietly(out);
// }
// }
//
//
//
//
// public MetadataTemplateManagerImpl() {
// // TODO Auto-generated constructor stub
// }
@Override
public Set<TemplateDescriptor> getAvailableTemplates() {
return new HashSet<>(templateDescriptors);
}
@Override
public MetadataReport applyTemplates(File original, Set<TemplateInvocation> invocations) {
MetadataReport report=new MetadataReport();
HashSet<String> appliedTemplates=new HashSet<>();
for(TemplateInvocation invocation:invocations){
try{
applyTemplate(original, invocation);
appliedTemplates.add(invocation.getToInvokeTemplateID());
}catch(Throwable t){
log.warn("Unable to apply template {} ",invocation.getToInvokeTemplateID());
}
}
report.setAppliedTemplates(appliedTemplates);
return report;
}
private static void applyTemplate(File original,TemplateInvocation invocation) throws Exception{
log.debug("Instantiating "+invocation);
AbstractTemplate tpl=availableTemplates.get(invocation.getToInvokeTemplateID());
if(tpl==null) throw new InvalidTemplateInvocationException("Template with ID "+invocation.getToInvokeTemplateID()+" was not found");
Writer out=null;
MetadataHandler handler=new MetadataHandler(original);
try{
Template temp = cfg.getTemplate(tpl.getFileName());
ByteArrayOutputStream baos=new ByteArrayOutputStream();
out=new OutputStreamWriter(baos);
temp.process(tpl.getInstantiationRequest(handler,invocation), out);
out.flush();
String instantiatedTemplate= baos.toString(StandardCharsets.UTF_8.toString());
//apply to original
handler.addContent(instantiatedTemplate, tpl.getInsertionPoint());
} catch (Exception e) {
log.error("Unable to apply template. Invocation was {} ",invocation,e);
throw e;
}finally{
if(out!=null)
IOUtils.closeQuietly(out);
}
}
}