001/*
002 *  Copyright 2012 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 */
016
017package org.ametys.runtime.plugins.admin.plugins.doc;
018
019import java.io.IOException;
020import java.io.InputStream;
021import java.util.Set;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.generation.ServiceableGenerator;
027import org.apache.cocoon.xml.AttributesImpl;
028import org.apache.cocoon.xml.XMLUtils;
029import org.apache.excalibur.source.Source;
030import org.apache.excalibur.source.SourceResolver;
031import org.apache.excalibur.xml.sax.SAXParser;
032import org.xml.sax.Attributes;
033import org.xml.sax.ContentHandler;
034import org.xml.sax.InputSource;
035import org.xml.sax.SAXException;
036
037import org.ametys.core.util.IgnoreRootHandler;
038import org.ametys.runtime.plugin.PluginsManager;
039
040/**
041 * Generates all the plugins.xml
042 */
043public class PluginDocGenerator extends ServiceableGenerator
044{
045    private SourceResolver _sourceResolver;
046    
047    @Override
048    public void service(ServiceManager smanager) throws ServiceException
049    {
050        super.service(smanager);
051        
052        _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE);
053    }
054    
055    @Override
056    public void generate() throws IOException, SAXException, ProcessingException
057    {
058        contentHandler.startDocument();
059        XMLUtils.startElement(contentHandler, "plugins");
060
061        Set<String> pluginNames = PluginsManager.getInstance().getPluginNames();
062        for (String pluginName : pluginNames)
063        {
064            _saxPlugin(pluginName);
065        }
066
067        XMLUtils.endElement(contentHandler, "plugins");
068        contentHandler.endDocument();
069    }
070
071    private void _saxPlugin(String pluginName) throws IOException, SAXException, ProcessingException
072    {
073        Source pluginSource = _sourceResolver.resolveURI("plugin:" + pluginName + "://plugin.xml");
074        SAXParser saxParser = null;
075        try (InputStream is = pluginSource.getInputStream())
076        {
077            saxParser = (SAXParser) manager.lookup(SAXParser.ROLE);
078            saxParser.parse(new InputSource(is), new SpecialHandler(contentHandler, pluginName));
079        }
080        catch (ServiceException e)
081        {
082            throw new ProcessingException("Unable to get a SAX parser", e);
083        }
084        finally
085        {
086            _sourceResolver.release(pluginSource);
087            manager.release(saxParser);
088        }
089    }
090
091    /**
092     * Ignore root handler that set the plugin name on the root tag 
093     */
094    public class SpecialHandler extends IgnoreRootHandler
095    {
096        private String _pluginName;
097        private int _level;
098        
099        /**
100         * Create a handler
101         * @param handler The handler to wrap
102         * @param pluginName The plugin name to set on root tag
103         */
104        public SpecialHandler(ContentHandler handler, String pluginName)
105        {
106            super(handler);
107            _pluginName = pluginName;
108        }
109        
110        /* (non-Javadoc)
111         * @see org.apache.excalibur.xml.sax.ContentHandlerProxy#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
112         */
113        @Override
114        public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException
115        {
116            _level++;
117            
118            if (_level == 1)
119            {
120                AttributesImpl attr = new AttributesImpl(a);
121                attr.addCDATAAttribute("name", _pluginName);
122
123                super.startElement(uri, loc, raw, attr);
124            }
125            else
126            {
127                super.startElement(uri, loc, raw, a);
128            }
129        }
130        
131        @Override
132        public void endElement(String uri, String loc, String raw) throws SAXException
133        {
134            _level--;
135            
136            super.endElement(uri, loc, raw);
137        }
138    }
139}