001/*
002 *  Copyright 2020 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.plugins.core.ui.resources.css;
017
018import java.io.IOException;
019
020import org.apache.avalon.framework.service.ServiceException;
021import org.apache.avalon.framework.service.ServiceManager;
022import org.apache.commons.lang.StringUtils;
023import org.apache.excalibur.source.Source;
024import org.apache.excalibur.source.SourceResolver;
025
026import org.ametys.core.resources.AbstractResourceHandlerProvider;
027import org.ametys.core.resources.CssResourceHandler;
028import org.ametys.core.resources.ResourceHandler;
029import org.ametys.core.resources.ResourceHandlerProvider;
030import org.ametys.plugins.core.ui.resources.css.less.LessResourceHandler;
031import org.ametys.plugins.core.ui.resources.css.sass.SassResourceHandler;
032
033/**
034 * {@link ResourceHandlerProvider} for compiled CSS files.
035 */
036public class CompiledCssResourceHandlerProvider extends AbstractResourceHandlerProvider
037{
038    private static final String[] __LESS_EXTENSION = new String[] {".less"};
039    private static final String[] __SASS_EXTENSION = new String[] {".scss", ".sass"};
040    
041    private SourceResolver _resolver;
042    
043    @Override
044    public void service(ServiceManager manager) throws ServiceException
045    {
046        super.service(manager);
047        _resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
048    }
049    
050    public int getPriority()
051    {
052        return MIN_PRIORITY + 1000;
053    }
054    
055    @Override
056    public ResourceHandler getResourceHandler(String source) throws Exception
057    {
058        String lcSource = StringUtils.lowerCase(source);
059        if (!StringUtils.endsWith(lcSource, ".css"))
060        {
061            return null;
062        }
063
064        // If the requested source exists, fallback to default CSS handler
065        Source src = _resolver.resolveURI(source);
066        if (src.exists())
067        {
068            return setup(new CssResourceHandler(src));
069        }
070        
071        _resolver.release(src);
072        
073        String sourceWithoutExt = StringUtils.substringBeforeLast(source, ".css");
074        
075        ResourceHandler handler = _getSassResourceHandler(sourceWithoutExt);
076        if (handler != null)
077        {
078            return handler;
079        }
080        
081        handler = _getLessResourceHandler(sourceWithoutExt);
082        if (handler != null)
083        {
084            return handler;
085        }
086        
087        return null;
088    }
089    
090    private ResourceHandler _getLessResourceHandler(String sourceWithoutExt) throws Exception
091    {
092        for (String ext : __LESS_EXTENSION)
093        {
094            try
095            {
096                Source src = _resolver.resolveURI(sourceWithoutExt + ext);
097                if (src.exists())
098                {
099                    return setup(new LessResourceHandler(src));
100                }
101                else
102                {
103                    _resolver.release(src);
104                }
105            }
106            catch (IOException e)
107            {
108                // Nothing
109            }
110        }
111        
112        return null;
113    }
114    
115    private ResourceHandler _getSassResourceHandler(String sourceWithoutExt) throws Exception
116    {
117        for (String ext : __SASS_EXTENSION)
118        {
119            Source src = null;
120            try
121            {
122                String sassLocation = StringUtils.removeEnd(sourceWithoutExt, ".min") + ext;
123                src = _resolver.resolveURI(sassLocation);
124                if (src.exists())
125                {
126                    return setup(new SassResourceHandler(src, sassLocation));
127                }
128                else
129                {
130                    _resolver.release(src);
131                }
132            }
133            catch (IOException e)
134            {
135                // Nothing
136            }
137        }
138        
139        return null;
140    }
141}