001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thierry Delprat
018 */
019package org.nuxeo.template.processors.jxls;
020
021import java.io.File;
022import java.io.IOException;
023import java.util.ArrayList;
024import java.util.List;
025import java.util.Map;
026
027import net.sf.jxls.exception.ParsePropertyException;
028import net.sf.jxls.transformer.XLSTransformer;
029
030import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
031import org.nuxeo.common.utils.FileUtils;
032import org.nuxeo.ecm.core.api.Blob;
033import org.nuxeo.ecm.core.api.Blobs;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.api.NuxeoException;
036import org.nuxeo.runtime.api.Framework;
037import org.nuxeo.template.api.TemplateInput;
038import org.nuxeo.template.api.TemplateProcessor;
039import org.nuxeo.template.api.adapters.TemplateBasedDocument;
040import org.nuxeo.template.context.SimpleContextBuilder;
041import org.nuxeo.template.processors.AbstractTemplateProcessor;
042
043/**
044 * JXLS {@link TemplateProcessor}
045 *
046 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
047 */
048public class JXLSTemplateProcessor extends AbstractTemplateProcessor {
049
050    public static final String TEMPLATE_TYPE = "JXLS";
051
052    protected SimpleContextBuilder contextBuilder = new SimpleContextBuilder();
053
054    @Override
055    public Blob renderTemplate(TemplateBasedDocument templateBasedDocument, String templateName) throws IOException {
056
057        Blob sourceTemplateBlob = getSourceTemplateBlob(templateBasedDocument, templateName);
058        List<TemplateInput> params = templateBasedDocument.getParams(templateName);
059
060        DocumentModel doc = templateBasedDocument.getAdaptedDoc();
061        Map<String, Object> ctx = contextBuilder.build(doc, templateName);
062
063        JXLSBindingResolver resolver = new JXLSBindingResolver();
064
065        resolver.resolve(params, ctx, templateBasedDocument);
066
067        File workingDir = getWorkingDir();
068        File generated = new File(workingDir, "JXLSresult-" + System.currentTimeMillis());
069        generated.createNewFile();
070
071        File input = new File(workingDir, "JXLSInput-" + System.currentTimeMillis());
072        input.createNewFile();
073
074        sourceTemplateBlob.transferTo(input);
075
076        XLSTransformer transformer = new XLSTransformer();
077        configureTransformer(transformer);
078        try {
079            transformer.transformXLS(input.getAbsolutePath(), ctx, generated.getAbsolutePath());
080        } catch (InvalidFormatException | ParsePropertyException e) {
081            throw new NuxeoException(e);
082        }
083
084        input.delete();
085
086        Blob newBlob = Blobs.createBlob(generated);
087
088        String templateFileName = sourceTemplateBlob.getFilename();
089
090        // set the output file name
091        String targetFileExt = FileUtils.getFileExtension(templateFileName);
092        String targetFileName = FileUtils.getFileNameNoExt(templateBasedDocument.getAdaptedDoc().getTitle());
093        targetFileName = targetFileName + "." + targetFileExt;
094        newBlob.setFilename(targetFileName);
095
096        // mark the file for automatic deletion on GC
097        Framework.trackFile(generated, newBlob);
098        return newBlob;
099
100    }
101
102    protected void configureTransformer(XLSTransformer transformer) {
103        // NOP but subclass may use this to register a CellProcessor or a
104        // RowProcessor
105    }
106
107    @Override
108    public List<TemplateInput> getInitialParametersDefinition(Blob blob) {
109        return new ArrayList<TemplateInput>();
110    }
111
112}