/***************************************************************************** * Copyright (c) 2008 g-Eclipse Consortium * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Initial development of the original code was made for the * g-Eclipse project founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributors: * Mathias Stuempert - initial API and implementation *****************************************************************************/ package eu.geclipse.core.config; import java.io.IOException; import java.io.OutputStream; import java.util.Hashtable; import java.util.Set; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.CoreException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import eu.geclipse.core.ICoreProblems; import eu.geclipse.core.internal.Activator; import eu.geclipse.core.reporting.ProblemException; /** * Concrete implementation of the {@link IConfiguration} interface. * Configuration parameters are stored using a hashtable. This implementation * provides a standard way of loading and saving a specific configuration from * and to XML files. */ public class Configuration implements IConfiguration { private static final String CONFIGURATION_ELEMENT = "configuration"; //$NON-NLS-1$ private static final String VERSION_ATTRIBUTE = "version"; //$NON-NLS-1$ private static final String VERSION_10 = "1.0"; //$NON-NLS-1$ private static final String PARAMETER_ELEMENT = "parameter"; //$NON-NLS-1$ private static final String KEY_ATTRIBUTE = "key"; //$NON-NLS-1$ private static final String VALUE_ELEMENT = "value"; //$NON-NLS-1$ /** * Internal hashtable holding the configuration parameters. */ private Hashtable< String, String[] > table = new Hashtable< String, String[] >(); /** * Standard constructor for an empty configuration. */ public Configuration() { // empty implementation } /** * Copy constructor. * * @param configuration The configuration to be copied. */ public Configuration( final IConfiguration configuration ) { Set< String > keys = configuration.getKeys(); for ( String key : keys ) { setParameters( key, configuration.getParameters( key ) ); } } /** * Sets a single-value parameter. * * @param key The parameter's key. * @param value The parameter's value. */ public void setParameter( final String key, final String value ) { setParameters( key, new String[] { value } ); } /** * Sets a multi-value parameter. * * @param key The parameter's key. * @param value The parameter's value. */ public void setParameters( final String key, final String[] value ) { this.table.put( key, value ); } /* (non-Javadoc) * @see eu.geclipse.core.config.IConfiguration#getKeys() */ public Set< String > getKeys() { return this.table.keySet(); } /* (non-Javadoc) * @see eu.geclipse.core.config.IConfiguration#getParameter(java.lang.String) */ public String getParameter( final String key ) { String[] parameters = this.table.get( key ); return ( parameters != null ) && ( parameters.length == 1 ) ? parameters[ 0 ] : null; } /* (non-Javadoc) * @see eu.geclipse.core.config.IConfiguration#getParameters(java.lang.String) */ public String[] getParameters( final String key ) { return this.table.get( key ); } /* (non-Javadoc) * @see eu.geclipse.core.config.IConfiguration#loadFromXML(org.eclipse.core.filesystem.IFileStore) */ public void loadFromXML( final IFileStore store ) throws ProblemException { this.table.clear(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating( false ); factory.setNamespaceAware( false ); DocumentBuilder dBuilder = factory.newDocumentBuilder(); Document document = dBuilder.parse( store.openInputStream( EFS.NONE, null ) ); NodeList configNodes = document.getElementsByTagName( CONFIGURATION_ELEMENT ); if ( configNodes.getLength() == 1 ) { Element configNode = ( Element ) configNodes.item( 0 ); String version = configNode.getAttribute( VERSION_ATTRIBUTE ); if ( VERSION_10.equals( version ) ) { NodeList parameterNodes = configNode.getElementsByTagName( PARAMETER_ELEMENT ); for ( int i = 0 ; i < parameterNodes.getLength() ; i++ ) { Element parameterNode = ( Element ) parameterNodes.item( i ); String key = parameterNode.getAttribute( KEY_ATTRIBUTE ); NodeList valueNodes = parameterNode.getElementsByTagName( VALUE_ELEMENT ); String[] values = new String[ valueNodes.getLength() ]; for ( int j = 0 ; j < valueNodes.getLength() ; j++ ) { values[ j ] = valueNodes.item( j ).getTextContent(); } setParameters( key, values ); } } } } catch ( ParserConfigurationException pcExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, pcExc, Activator.PLUGIN_ID ); } catch( SAXException saxExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, saxExc, Activator.PLUGIN_ID ); } catch( IOException ioExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, ioExc, Activator.PLUGIN_ID ); } catch( CoreException cExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, cExc, Activator.PLUGIN_ID ); } } /* (non-Javadoc) * @see eu.geclipse.core.config.IConfiguration#storeToXML(org.eclipse.core.filesystem.IFileStore) */ public void storeToXML( final IFileStore store ) throws ProblemException { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating( false ); factory.setNamespaceAware( false ); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Element configNode = document.createElement( CONFIGURATION_ELEMENT ); configNode.setAttribute( VERSION_ATTRIBUTE, VERSION_10 ); document.appendChild( configNode ); Set< String > keys = getKeys(); for ( String key : keys ) { String[] parameters = getParameters( key ); if ( ( parameters != null ) && ( parameters.length > 0 ) ) { Element parNode = document.createElement( PARAMETER_ELEMENT ); parNode.setAttribute( KEY_ATTRIBUTE, key ); configNode.appendChild( parNode ); for ( String value : parameters ) { Element valNode = document.createElement( VALUE_ELEMENT ); parNode.appendChild( valNode ); valNode.appendChild( document.createTextNode( value ) ); } } } OutputStream oStream = store.openOutputStream( EFS.NONE, null ); DOMSource domSource = new DOMSource( document ); StreamResult streamResult = new StreamResult( oStream ); TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(); transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); //$NON-NLS-1$ transformer.transform( domSource, streamResult ); oStream.close(); } catch ( ParserConfigurationException pcExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, pcExc, Activator.PLUGIN_ID ); } catch( CoreException cExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, cExc, Activator.PLUGIN_ID ); } catch( TransformerConfigurationException tcExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, tcExc, Activator.PLUGIN_ID ); } catch( TransformerException tExc ) { throw new ProblemException( ICoreProblems.IO_OPERATION_FAILED, tExc, Activator.PLUGIN_ID ); } catch( IOException ioExc ) { // Coming from close() -> Ignoring } } }