001/*
002 *  Copyright 2018 Anyware Services
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 */
016package org.ametys.core.minimize.css.sass;
017
018import java.io.ByteArrayOutputStream;
019import java.io.IOException;
020import java.io.InputStream;
021import java.io.Serializable;
022import java.net.URISyntaxException;
023import java.nio.charset.StandardCharsets;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.caching.CacheableProcessingComponent;
029import org.apache.cocoon.reading.ServiceableReader;
030import org.apache.commons.io.IOUtils;
031import org.apache.excalibur.source.Source;
032import org.apache.excalibur.source.SourceResolver;
033import org.apache.excalibur.source.SourceValidity;
034import org.apache.excalibur.source.impl.validity.NOPValidity;
035import org.xml.sax.SAXException;
036
037import io.bit3.jsass.CompilationException;
038
039/**
040 * Reader that compile a sass file into css
041 */
042public class CompileSassReader extends ServiceableReader implements CacheableProcessingComponent
043{
044    
045    private MinimizeSassManager _minimizeSassManager;
046    private SourceResolver _resolver;
047
048    @Override
049    public void service(ServiceManager smanager) throws ServiceException
050    {
051        super.service(smanager);
052        _minimizeSassManager = (MinimizeSassManager) smanager.lookup(MinimizeSassManager.ROLE);
053        _resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
054    }
055    
056    @SuppressWarnings("deprecation")
057    @Override
058    public void generate() throws IOException, SAXException, ProcessingException
059    {
060        try
061        {
062            Source src = _resolver.resolveURI(this.source);
063            if (!src.exists())
064            {
065                throw new ProcessingException("Unable to resolve sass file '" + source + "' for compilation, source does not exist");
066            }
067            
068            try (ByteArrayOutputStream bos = new ByteArrayOutputStream())
069            {
070                try (InputStream is = src.getInputStream())
071                {
072                    IOUtils.copy(is, bos);
073                }
074                
075                String compileCss = _minimizeSassManager.compileCss(bos.toString(StandardCharsets.UTF_8.toString()), source, source, false, 0);
076                IOUtils.write(compileCss, out, StandardCharsets.UTF_8);
077                IOUtils.closeQuietly(out);
078            }
079            catch (URISyntaxException | CompilationException e)
080            {
081                throw new ProcessingException("Unable to compile sass file '" + source + "'", e);
082            }
083            
084        }
085        catch (IOException e)
086        {
087            throw new ProcessingException("Unable to resolve sass file '" + source + "' for compilation", e);
088        }
089    }
090
091    @Override
092    public Serializable getKey()
093    {
094        return this.source;
095    }
096
097    @Override
098    public SourceValidity getValidity()
099    {
100        return new NOPValidity();
101    }
102
103    @Override
104    public String getMimeType()
105    {
106        return "text/css";
107    }
108    
109}