001/*
002 *  Copyright 2010 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.web.source;
017
018import java.io.IOException;
019import java.net.MalformedURLException;
020import java.util.Map;
021import java.util.regex.Matcher;
022import java.util.regex.Pattern;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.avalon.framework.service.Serviceable;
027import org.apache.excalibur.source.Source;
028import org.apache.excalibur.source.SourceFactory;
029
030import org.ametys.core.util.path.PathSource;
031import org.ametys.runtime.plugin.component.AbstractLogEnabled;
032import org.ametys.web.skin.SkinModel;
033import org.ametys.web.skin.SkinModelsManager;
034
035/**
036 * Resolve the protocol model:// seeking file in models/
037 */
038public class ModelSourceFactory extends AbstractLogEnabled implements SourceFactory, Serviceable
039{
040    /** The regexp for a protocol */
041    protected static final Pattern __SOURCE_PATTERN = Pattern.compile("^[\\w]+:([^:#]+)://([^?]*)(?:\\?.*)?$");
042    
043    /** Scheme for model */
044    protected static final String __MODEL_SCHEME = "model";
045    
046    /** The skins manager */
047    protected SkinModelsManager _skinModelsManager;
048
049    private ServiceManager _manager;
050    
051    @Override
052    public void service(ServiceManager manager) throws ServiceException
053    {
054        _manager = manager;
055    }
056    
057    /**
058     * Lookup {@link SkinModelsManager} for lazy initialization.
059     */
060    protected void initializeComponents()
061    {
062        try
063        {
064            if (_skinModelsManager == null)
065            {
066                _skinModelsManager = (SkinModelsManager) _manager.lookup(SkinModelsManager.ROLE);
067            }
068        }
069        catch (ServiceException e)
070        {
071            throw new IllegalStateException("Exception while getting components", e);
072        }
073    }
074
075    @Override
076    public Source getSource(String location, Map parameters) throws IOException
077    {
078        // lazy initialization to prevent chicken/egg scenario on startup
079        initializeComponents();
080        
081        Matcher m = __SOURCE_PATTERN.matcher(location);
082        if (!m.matches())
083        {
084            throw new MalformedURLException("URI must be like protocol:<name>://path/to/resource. Location was '" + location + "'");
085        }
086        
087        String modelId = m.group(1);
088        String fileLocation = m.group(2);
089        
090        SkinModel skinModel = _skinModelsManager.getModel(modelId);
091        return new PathSource(__MODEL_SCHEME, location, skinModel.getPath().resolve(fileLocation));
092    }
093
094    public void release(Source source)
095    {
096        // Nothing to do
097    }
098}