/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.studio.ldapservers;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.directory.studio.ldapservers.model.LdapServer;
import org.apache.directory.studio.ldapservers.model.LdapServerAdapterExtension;
import org.apache.directory.studio.ldapservers.model.UnknownLdapServerAdapterExtension;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* This class is used to read/write the 'servers.xml' file.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LdapServersManagerIO
{
// XML tags and attributes
private static final String LDAP_SERVERS_TAG = "ldapServers"; //$NON-NLS-1$
private static final String LDAP_SERVER_TAG = "ldapServer"; //$NON-NLS-1$
private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$
private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$
private static final String ADAPTER_ID_ATTRIBUTE = "adapterId"; //$NON-NLS-1$
private static final String ADAPTER_NAME_ATTRIBUTE = "adapterName"; //$NON-NLS-1$
private static final String ADAPTER_VENDOR_ATTRIBUTE = "adapterVendor"; //$NON-NLS-1$
private static final String ADAPTER_VERSION_ATTRIBUTE = "adapterVersion"; //$NON-NLS-1$
private static final String CONFIGURATION_PARAMETERS_TAG = "configurationParameters"; //$NON-NLS-1$
private static final String ENTRY_TAG = "entry"; //$NON-NLS-1$
private static final String KEY_ATTRIBUTE = "key"; //$NON-NLS-1$
private static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$
private static final String VALUE_ATTRIBUTE = "value"; //$NON-NLS-1$
/**
* Reads the given input stream.
*
* @param stream
* the input stream
* @return
* the list of LDAP Servers found in the input stream
* @throws LdapServersManagerIOException
*/
public static List<LdapServer> read( InputStream stream ) throws LdapServersManagerIOException
{
List<LdapServer> servers = new ArrayList<LdapServer>();
SAXReader saxReader = new SAXReader();
Document document = null;
try
{
document = saxReader.read( stream );
}
catch ( DocumentException e )
{
throw new LdapServersManagerIOException( e.getMessage() );
}
Element rootElement = document.getRootElement();
if ( !rootElement.getName().equals( LDAP_SERVERS_TAG ) )
{
throw new LdapServersManagerIOException(
Messages.getString( "LdapServersManagerIO.ErrorNotValidServersFile" ) ); //$NON-NLS-1$
}
for ( Iterator<?> i = rootElement.elementIterator( LDAP_SERVER_TAG ); i.hasNext(); )
{
servers.add( readLdapServer( ( Element ) i.next() ) );
}
return servers;
}
/**
* Reads an LDAP Server element.
*
* @param element
* the element
* @return
* the corresponding {@link LdapServer}
*/
private static LdapServer readLdapServer( Element element )
{
LdapServer server = new LdapServer();
// ID
Attribute idAttribute = element.attribute( ID_ATTRIBUTE );
if ( idAttribute != null )
{
server.setId( idAttribute.getValue() );
}
// Name
Attribute nameAttribute = element.attribute( NAME_ATTRIBUTE );
if ( nameAttribute != null )
{
server.setName( nameAttribute.getValue() );
}
// Adapter ID
Attribute adapterIdAttribute = element.attribute( ADAPTER_ID_ATTRIBUTE );
if ( adapterIdAttribute != null )
{
// Getting the id
String adapterId = adapterIdAttribute.getValue();
// Looking for the correct LDAP Server Adapter Extension object
LdapServerAdapterExtension ldapServerAdapterExtension = LdapServerAdapterExtensionsManager.getDefault()
.getLdapServerAdapterExtensionById( adapterId );
if ( ldapServerAdapterExtension != null )
{
// The Adapter Extension has been found
// Assigning it to the server
server.setLdapServerAdapterExtension( ldapServerAdapterExtension );
}
else
{
// The Adapter Extension has not been found
// Creating an "unknown" Adapter Extension
UnknownLdapServerAdapterExtension unknownLdapServerAdapterExtension = new UnknownLdapServerAdapterExtension();
// Adapter Id
unknownLdapServerAdapterExtension.setId( adapterId );
// Adapter Name
Attribute adapterNameAttribute = element.attribute( ADAPTER_NAME_ATTRIBUTE );
if ( adapterNameAttribute != null )
{
unknownLdapServerAdapterExtension.setName( adapterNameAttribute.getValue() );
}
// Adapter Vendor
Attribute adapterVendorAttribute = element.attribute( ADAPTER_VENDOR_ATTRIBUTE );
if ( adapterVendorAttribute != null )
{
unknownLdapServerAdapterExtension.setVendor( adapterVendorAttribute.getValue() );
}
// Adapter Version
Attribute adapterVersionAttribute = element.attribute( ADAPTER_VERSION_ATTRIBUTE );
if ( adapterVersionAttribute != null )
{
unknownLdapServerAdapterExtension.setVersion( adapterVersionAttribute.getValue() );
}
// Assigning the "unknown" Adapter Extension to the server
server.setLdapServerAdapterExtension( unknownLdapServerAdapterExtension );
}
}
else
{
// TODO No Adapter ID, throw an error ?
}
// Configuration Parameters
Element configurationParametersElement = element.element( CONFIGURATION_PARAMETERS_TAG );
if ( configurationParametersElement != null )
{
for ( Iterator<?> i = configurationParametersElement.elementIterator( ENTRY_TAG ); i.hasNext(); )
{
readConfigurationParameter( server, ( Element ) i.next() );
}
}
return server;
}
/**
* Reads a configuration parameter.
*
* @param server the server
* @param element the element
*/
private static void readConfigurationParameter( LdapServer server, Element element )
{
// Key
Attribute keyAttribute = element.attribute( KEY_ATTRIBUTE );
String key = null;
if ( keyAttribute != null )
{
key = keyAttribute.getValue();
// Value
Attribute valueAttribute = element.attribute( VALUE_ATTRIBUTE );
String value = null;
if ( valueAttribute != null )
{
value = valueAttribute.getValue();
}
// Type
Attribute typeAttribute = element.attribute( TYPE_ATTRIBUTE );
String type = null;
if ( typeAttribute != null )
{
type = typeAttribute.getValue();
}
// Integer value
if ( ( type != null ) && ( type.equalsIgnoreCase( Integer.class.getCanonicalName() ) ) )
{
server.putConfigurationParameter( key, Integer.parseInt( value ) );
}
// Boolean value
else if ( ( type != null ) && ( type.equalsIgnoreCase( Boolean.class.getCanonicalName() ) ) )
{
server.putConfigurationParameter( key, Boolean.parseBoolean( value ) );
}
// String value (default type)
else
{
server.putConfigurationParameter( key, value );
}
}
}
/**
* Writes the list of servers to the given stream.
*
* @param servers
* the servers
* @param outputStream
* the output stream
* @throws IOException
* if an error occurs when writing to the stream
*/
public static void write( List<LdapServer> servers, OutputStream outputStream ) throws IOException
{
// Creating the Document
Document document = DocumentHelper.createDocument();
// Creating the root element
Element root = document.addElement( LDAP_SERVERS_TAG );
if ( servers != null )
{
for ( LdapServer server : servers )
{
addLdapServer( server, root );
}
}
// Writing the file to the stream
OutputFormat outformat = OutputFormat.createPrettyPrint();
outformat.setEncoding( "UTF-8" ); //$NON-NLS-1$
XMLWriter writer = new XMLWriter( outputStream, outformat );
writer.write( document );
writer.flush();
}
/**
* Adds the XML representation of the LDAP Server to the given parent.
*
* @param server
* the server
* @param parent
* the parent element
*/
private static void addLdapServer( LdapServer server, Element parent )
{
// Server element
Element serverElement = parent.addElement( LDAP_SERVER_TAG );
// ID
serverElement.addAttribute( ID_ATTRIBUTE, server.getId() );
// Name
serverElement.addAttribute( NAME_ATTRIBUTE, server.getName() );
// Adapter ID
serverElement.addAttribute( ADAPTER_ID_ATTRIBUTE, server.getLdapServerAdapterExtension().getId() );
// Adapter Name
serverElement.addAttribute( ADAPTER_NAME_ATTRIBUTE, server.getLdapServerAdapterExtension().getName() );
// Adapter Vendor
serverElement.addAttribute( ADAPTER_VENDOR_ATTRIBUTE, server.getLdapServerAdapterExtension().getVendor() );
// Adapter Version
serverElement.addAttribute( ADAPTER_VERSION_ATTRIBUTE, server.getLdapServerAdapterExtension().getVersion() );
// Configuration Parameters
Map<String, Object> configurationParametersMap = server.getConfigurationParameters();
if ( ( configurationParametersMap != null ) && ( configurationParametersMap.size() > 0 ) )
{
addConfigurationParameters( configurationParametersMap, serverElement );
}
}
/**
* Adds the XML representation of the configuration elements to the given parent.
*
* @param map the configuration elements map
* @param element the parent element
*/
private static void addConfigurationParameters( Map<String, Object> map, Element parent )
{
// Configuration Parameters element
Element configurationParametersElement = parent.addElement( CONFIGURATION_PARAMETERS_TAG );
// Get the keys of the map
Set<Entry<String, Object>> entriesSet = map.entrySet();
for ( Entry<String, Object> entry : entriesSet )
{
// Entry element
Element entryElement = configurationParametersElement.addElement( ENTRY_TAG );
// Key
entryElement.addAttribute( KEY_ATTRIBUTE, entry.getKey() );
// Value
Object value = entry.getValue();
entryElement.addAttribute( VALUE_ATTRIBUTE, value.toString() );
// Type
if ( value.getClass() != String.class )
{
entryElement.addAttribute( TYPE_ATTRIBUTE, value.getClass().getCanonicalName() );
}
}
}
}