/* * 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.connection.core; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.Set; import org.apache.directory.api.util.FileUtils; import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry; import org.apache.directory.studio.connection.core.event.ConnectionUpdateListener; import org.apache.directory.studio.connection.core.io.ConnectionIO; import org.apache.directory.studio.connection.core.io.ConnectionIOException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; /** * This class is used to manage {@link Connection}s. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class ConnectionManager implements ConnectionUpdateListener { private static final String LOGS_PATH = "logs"; //$NON-NLS-1$ private static final String SEARCH_LOGS_PREFIX = "search-"; //$NON-NLS-1$ private static final String MODIFICATIONS_LOG_PREFIX = "modifications-"; //$NON-NLS-1$ private static final String LDIFLOG_SUFFIX = "-%u-%g.ldiflog"; //$NON-NLS-1$ private static final String CONNECTIONS_XML = "connections.xml"; //$NON-NLS-1$ public static final String ENCODING_UTF8 = "UTF-8"; //$NON-NLS-1$ public static final String TEMP_SUFFIX = "-temp"; //$NON-NLS-1$ /** The list of connections. */ private Set<Connection> connectionList; /** * Creates a new instance of ConnectionManager. */ public ConnectionManager() { this.connectionList = new HashSet<Connection>(); loadInitializers(); loadConnections(); ConnectionEventRegistry.addConnectionUpdateListener( this, ConnectionCorePlugin.getDefault().getEventRunner() ); } /** * Loads the Connection Initializers. This happens only for the first time, * which is determined by whether or not the connectionStore file is present. */ private void loadInitializers() { File connectionStore = new File( getConnectionStoreFileName() ); if ( connectionStore.exists() ) { return; // connections are stored from a previous sessions - don't call initializers } IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint( ConnectionCorePlugin.getDefault().getPluginProperties() .getString( "ExtensionPoint_ConnectionInitializer_id" ) ); //$NON-NLS-1$ IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements(); for ( IConfigurationElement configurationElement : configurationElements ) { if ( "connection".equals( configurationElement.getName() ) ) //$NON-NLS-1$ { addInitialConnection( configurationElement ); } } } /** * Creates the ConnectionParameter from the configElement and creates the connection. * * @param configurationElement The configuration element */ private void addInitialConnection( IConfigurationElement configurationElement ) { try { ConnectionParameter connectionParameter = ( ConnectionParameter ) configurationElement .createExecutableExtension( "class" ); //$NON-NLS-1$ Connection conn = new Connection( connectionParameter ); connectionList.add( conn ); } catch ( CoreException e ) { Status status = new Status( IStatus.ERROR, ConnectionCoreConstants.PLUGIN_ID, Messages.error__execute_connection_initializer + e.getMessage(), e ); ConnectionCorePlugin.getDefault().getLog().log( status ); } } /** * Gets the Modification Log filename for the corresponding connection. * * @param connection * the connection * @return * the Modification Log filename */ public static final String getModificationLogFileName( Connection connection ) { IPath p = ConnectionCorePlugin.getDefault().getStateLocation().append( LOGS_PATH ); File file = p.toFile(); if ( !file.exists() ) { file.mkdir(); } return p.append( MODIFICATIONS_LOG_PREFIX + Utils.getFilenameString( connection.getId() ) + LDIFLOG_SUFFIX ) .toOSString(); } /** * Gets the Search Log filename for the corresponding connection. * * @param connection * the connection * @return * the Search Log filename */ public static final String getSearchLogFileName( Connection connection ) { IPath p = ConnectionCorePlugin.getDefault().getStateLocation().append( LOGS_PATH ); //$NON-NLS-1$ File file = p.toFile(); if ( !file.exists() ) { file.mkdir(); } return p.append( SEARCH_LOGS_PREFIX + Utils.getFilenameString( connection.getId() ) + LDIFLOG_SUFFIX ) .toOSString(); } /** * Gets the filename of the Connection Store. * * @return * the filename of the Connection Store */ public static final String getConnectionStoreFileName() { String filename = ConnectionCorePlugin.getDefault().getStateLocation().append( CONNECTIONS_XML ).toOSString(); return filename; } /** * Adds the connection to the end of the connection list. If there is * already a connection with this name, the new connection is renamed. * * @param connection the connection to add */ public void addConnection( Connection connection ) { if ( getConnectionByName( connection.getConnectionParameter().getName() ) != null ) { String newConnectionName = Messages.bind( Messages.copy_n_of_s, "", connection.getConnectionParameter().getName() ); //$NON-NLS-1$ for ( int i = 2; getConnectionByName( newConnectionName ) != null; i++ ) { newConnectionName = Messages.bind( Messages.copy_n_of_s, i + " ", connection.getConnectionParameter().getName() ); //$NON-NLS-1$ } connection.getConnectionParameter().setName( newConnectionName ); } connectionList.add( connection ); ConnectionEventRegistry.fireConnectionAdded( connection, this ); } /** * Gets a connection from its id. * * @param id * the id of the Connection * @return * the corresponding Connection */ public Connection getConnectionById( String id ) { for ( Connection conn : connectionList ) { if ( conn.getConnectionParameter().getId().equals( id ) ) { return conn; } } return null; } /** * Gets a connection from its name. * * @param name * the name of the Connection * @return * the corresponding Connection */ public Connection getConnectionByName( String name ) { for ( Connection conn : connectionList ) { if ( conn.getConnectionParameter().getName().equals( name ) ) { return conn; } } return null; } /** * Removes the given Connection from the Connection list. * * @param connection * the connection to remove */ public void removeConnection( Connection connection ) { connectionList.remove( connection ); ConnectionEventRegistry.fireConnectionRemoved( connection, this ); } /** * Gets an array containing all the Connections. * * @return * an array containing all the Connections */ public Connection[] getConnections() { return ( Connection[] ) connectionList.toArray( new Connection[0] ); } /** * Gets the number of Connections. * * @return * the number of Connections */ public int getConnectionCount() { return connectionList.size(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionAdded(org.apache.directory.studio.connection.core.Connection) */ public void connectionAdded( Connection connection ) { saveConnections(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionRemoved(org.apache.directory.studio.connection.core.Connection) */ public void connectionRemoved( Connection connection ) { saveConnections(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionUpdated(org.apache.directory.studio.connection.core.Connection) */ public void connectionUpdated( Connection connection ) { saveConnections(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionOpened(org.apache.directory.studio.connection.core.Connection) */ public void connectionOpened( Connection connection ) { } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionClosed(org.apache.directory.studio.connection.core.Connection) */ public void connectionClosed( Connection connection ) { } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionFolderModified(org.apache.directory.studio.connection.core.ConnectionFolder) */ public void connectionFolderModified( ConnectionFolder connectionFolder ) { } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionFolderAdded(org.apache.directory.studio.connection.core.ConnectionFolder) */ public void connectionFolderAdded( ConnectionFolder connectionFolder ) { } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionFolderRemoved(org.apache.directory.studio.connection.core.ConnectionFolder) */ public void connectionFolderRemoved( ConnectionFolder connectionFolder ) { } /** * Saves the Connections */ public synchronized void saveConnections() { Set<ConnectionParameter> connectionParameters = new HashSet<ConnectionParameter>(); for ( Connection connection : connectionList ) { connectionParameters.add( connection.getConnectionParameter() ); } // To avoid a corrupt file, save object to a temp file first try { ConnectionIO .save( connectionParameters, new FileOutputStream( getConnectionStoreFileName() + TEMP_SUFFIX ) ); } catch ( IOException e ) { Status status = new Status( IStatus.ERROR, ConnectionCoreConstants.PLUGIN_ID, Messages.error__saving_connections + e.getMessage(), e ); ConnectionCorePlugin.getDefault().getLog().log( status ); } // move temp file to good file File file = new File( getConnectionStoreFileName() ); File tempFile = new File( getConnectionStoreFileName() + TEMP_SUFFIX ); if ( file.exists() ) { file.delete(); } try { String content = FileUtils.readFileToString( tempFile, ENCODING_UTF8 ); FileUtils.writeStringToFile( file, content, ENCODING_UTF8 ); } catch ( IOException e ) { Status status = new Status( IStatus.ERROR, ConnectionCoreConstants.PLUGIN_ID, Messages.error__saving_connections + e.getMessage(), e ); ConnectionCorePlugin.getDefault().getLog().log( status ); } } /** * Loads the Connections */ private synchronized void loadConnections() { Set<ConnectionParameter> connectionParameters = null; try { connectionParameters = ConnectionIO.load( new FileInputStream( getConnectionStoreFileName() ) ); } catch ( Exception e ) { // If loading failed, try with temp file try { connectionParameters = ConnectionIO.load( new FileInputStream( getConnectionStoreFileName() + TEMP_SUFFIX ) ); } catch ( FileNotFoundException e1 ) { // ignore, this is a fresh workspace return; } catch ( ConnectionIOException e1 ) { Status status = new Status( IStatus.ERROR, ConnectionCoreConstants.PLUGIN_ID, Messages.error__loading_connections + e.getMessage(), e ); ConnectionCorePlugin.getDefault().getLog().log( status ); } } if ( connectionParameters != null ) { for ( ConnectionParameter connectionParameter : connectionParameters ) { Connection conn = new Connection( connectionParameter ); connectionList.add( conn ); } } } }