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    private SAXParser _saxParser;
047    
048    @Override
049    public void service(ServiceManager smanager) throws ServiceException
050    {
051        super.service(smanager);
052        
053        _sourceResolver = (SourceResolver) smanager.lookup(SourceResolver.ROLE);
054        _saxParser = (SAXParser) smanager.lookup(SAXParser.ROLE);
055    }
056    
057    @Override
058    public void generate() throws IOException, SAXException, ProcessingException
059    {
060        contentHandler.startDocument();
061        XMLUtils.startElement(contentHandler, "plugins");
062
063        Set<String> pluginNames = PluginsManager.getInstance().getPluginNames();
064        for (String pluginName : pluginNames)
065        {
066            _saxPlugin(pluginName);
067        }
068
069        XMLUtils.endElement(contentHandler, "plugins");
070        contentHandler.endDocument();
071    }
072
073    private void _saxPlugin(String pluginName) throws IOException, SAXException
074    {
075        Source pluginSource = _sourceResolver.resolveURI("plugin:" + pluginName + "://plugin.xml");
076        try (InputStream is = pluginSource.getInputStream())
077        {
078            _saxParser.parse(new InputSource(is), new SpecialHandler(contentHandler, pluginName));
079        }
080        finally
081        {
082            _sourceResolver.release(pluginSource);
083        }
084    }
085
086    /**
087     * Ignore root handler that set the plugin name on the root tag 
088     */
089    public class SpecialHandler extends IgnoreRootHandler
090    {
091        private String _pluginName;
092        private int _level;
093        
094        /**
095         * Create a handler
096         * @param handler The handler to wrap
097         * @param pluginName The plugin name to set on root tag
098         */
099        public SpecialHandler(ContentHandler handler, String pluginName)
100        {
101            super(handler);
102            _pluginName = pluginName;
103        }
104        
105        /* (non-Javadoc)
106         * @see org.apache.excalibur.xml.sax.ContentHandlerProxy#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
107         */
108        @Override
109        public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException
110        {
111            _level++;
112            
113            if (_level == 1)
114            {
115                AttributesImpl attr = new AttributesImpl(a);
116                attr.addCDATAAttribute("name", _pluginName);
117
118                super.startElement(uri, loc, raw, attr);
119            }
120            else
121            {
122                super.startElement(uri, loc, raw, a);
123            }
124        }
125        
126        @Override
127        public void endElement(String uri, String loc, String raw) throws SAXException
128        {
129            _level--;
130            
131            super.endElement(uri, loc, raw);
132        }
133    }
134}