001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.web.resources.wro.processor;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.io.OutputStream;
022import java.io.Reader;
023import java.io.Writer;
024import java.util.Map;
025import java.util.regex.Matcher;
026import java.util.regex.Pattern;
027
028import org.apache.commons.io.IOUtils;
029import org.apache.commons.io.input.ProxyInputStream;
030import org.apache.commons.io.input.ReaderInputStream;
031import org.apache.commons.io.output.ProxyOutputStream;
032import org.apache.commons.io.output.WriterOutputStream;
033import org.apache.commons.logging.Log;
034import org.apache.commons.logging.LogFactory;
035import org.nuxeo.runtime.api.Framework;
036import org.nuxeo.theme.styling.service.ThemeStylingService;
037
038import ro.isdc.wro.WroRuntimeException;
039import ro.isdc.wro.model.resource.Resource;
040import ro.isdc.wro.model.resource.ResourceType;
041import ro.isdc.wro.model.resource.SupportedResourceType;
042
043/**
044 * Wro processor to replace flavor variables inside linked CSS file.
045 *
046 * @since 7.3
047 */
048@SupportedResourceType(ResourceType.CSS)
049public class FlavorResourceProcessor extends AbstractFlavorProcessor {
050
051    private static final Log log = LogFactory.getLog(FlavorResourceProcessor.class);
052
053    public static final String ALIAS = "flavor";
054
055    @Override
056    protected void process(final Resource resource, final Reader reader, final Writer writer, String flavorName)
057            throws IOException {
058        final InputStream is = new ProxyInputStream(new ReaderInputStream(reader, getEncoding())) {
059        };
060        final OutputStream os = new ProxyOutputStream(new WriterOutputStream(writer, getEncoding()));
061        try {
062            Map<String, String> presets = null;
063            if (flavorName != null) {
064                ThemeStylingService s = Framework.getService(ThemeStylingService.class);
065                presets = s.getPresetVariables(flavorName);
066            }
067            if (presets == null || presets.isEmpty()) {
068                IOUtils.copy(is, os);
069            } else {
070                String content = IOUtils.toString(reader);
071                for (Map.Entry<String, String> preset : presets.entrySet()) {
072                    content = Pattern.compile(String.format("\"%s\"", preset.getKey()), Pattern.LITERAL).matcher(
073                            content).replaceAll(Matcher.quoteReplacement(preset.getValue()));
074                }
075                writer.write(content);
076                writer.flush();
077            }
078            is.close();
079        } catch (final Exception e) {
080            log.error("Error while serving resource " + resource.getUri(), e);
081            throw WroRuntimeException.wrap(e);
082        } finally {
083            IOUtils.closeQuietly(is);
084            IOUtils.closeQuietly(os);
085        }
086    }
087
088    @Override
089    public String getAlias() {
090        return ALIAS;
091    }
092
093}