/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.libraries.base.config.metadata;
import org.pentaho.reporting.libraries.base.boot.AbstractBoot;
import org.pentaho.reporting.libraries.base.boot.Module;
import org.pentaho.reporting.libraries.base.util.StringUtils;
import org.pentaho.reporting.libraries.base.util.XMLParserFactoryProducer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
public class ConfigurationMetaDataParser {
/**
* Parses the given input stream to form a document.
*
* @param instream the input stream that should be parsed.
* @return the parsed document or <code>null</code>, when an error occured
* @throws javax.xml.parsers.ParserConfigurationException if the parser could not be initalized.
* @throws org.xml.sax.SAXException if the parsing failed due to errors in the xml document
* @throws java.io.IOException if reading from the input stream failed.
*/
private static Document parseInputStream( final InputStream instream )
throws ParserConfigurationException, SAXException, IOException {
final DocumentBuilderFactory dbf = XMLParserFactoryProducer.createSecureDocBuilderFactory();
final DocumentBuilder db = dbf.newDocumentBuilder();
return db.parse( new InputSource( instream ) );
}
public void parse( final InputStream in, final String domain ) throws IOException {
try {
final ConfigurationDomain d = ConfigurationMetaData.getInstance().createDomain( domain );
final Document doc = parseInputStream( in );
final Element documentElement = doc.getDocumentElement();
final NodeList keys = documentElement.getElementsByTagName( "key" );
for ( int i = 0; i < keys.getLength(); i += 1 ) {
final ConfigurationMetaDataEntry entr = parseEntry( (Element) keys.item( i ) );
d.add( entr );
}
} catch ( ParserConfigurationException e ) {
throw new IOException( e );
} catch ( SAXException e ) {
throw new IOException( e );
}
}
private ConfigurationMetaDataEntry parseEntry( final Element item ) throws IOException {
final String name = item.getAttribute( "name" );
if ( StringUtils.isEmpty( name ) ) {
throw new IOException( "Name for entry is null" );
}
final ConfigurationMetaDataEntry entry = new ConfigurationMetaDataEntry( name );
entry.setDescription( getText( item, "description" ) );
entry.setClassName( getClass( item ) );
entry.setGlobal( "true".equals( item.getAttribute( "global" ) ) );
entry.setHidden( "true".equals( item.getAttribute( "hidden" ) ) );
parseEnum( item, entry );
return entry;
}
private void parseEnum( final Element item, final ConfigurationMetaDataEntry entry ) {
final NodeList nl = item.getElementsByTagName( "enum" );
if ( nl.getLength() > 0 ) {
final Element enumElement = (Element) nl.item( 0 );
final NodeList textNl = enumElement.getElementsByTagName( "text" );
for ( int i = 0; i < textNl.getLength(); i++ ) {
final Element text = (Element) textNl.item( i );
entry.addTag( text.getTextContent(), text.getTextContent() );
}
final NodeList entryNl = enumElement.getElementsByTagName( "entry" );
for ( int i = 0; i < entryNl.getLength(); i++ ) {
final Element text = (Element) entryNl.item( i );
entry.addTag( getText( text, "text" ), getText( text, "display-name" ) );
}
}
}
private String getClass( final Element base ) {
final NodeList nl = base.getElementsByTagName( "class" );
if ( nl.getLength() > 0 ) {
final Element descElement = (Element) nl.item( 0 );
final String attr = descElement.getAttribute( "instanceof" );
if ( StringUtils.isEmpty( attr ) == false ) {
return attr;
}
}
return null;
}
private String getText( final Element base, final String elementName ) {
final NodeList nl = base.getElementsByTagName( elementName );
if ( nl.getLength() > 0 ) {
final Element descElement = (Element) nl.item( 0 );
return descElement.getTextContent();
}
return null;
}
public void parseConfiguration( final AbstractBoot boot ) throws IOException {
final String domain = boot.getConfigurationDomain();
final Module[] activeModules = boot.getPackageManager().getActiveModules();
for ( int i = 0; i < activeModules.length; i++ ) {
final Module activeModule = activeModules[ i ];
final InputStream resourceAsStream = activeModule.getClass().getResourceAsStream( "config-description.xml" );
if ( resourceAsStream != null ) {
try {
parse( resourceAsStream, domain );
} finally {
resourceAsStream.close();
}
}
}
}
}