/* * 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.ArrayList; import java.util.HashSet; import java.util.List; 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; /** * This class is used to manage {@link ConnectionFolder}s. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class ConnectionFolderManager implements ConnectionUpdateListener { private static final String CONNECTION_FOLDERS_FILENAME = "connectionFolders.xml"; //$NON-NLS-1$ private static final String ROOT_ID = "0"; //$NON-NLS-1$ /** The root connection folder. */ private ConnectionFolder root; /** The list of folders. */ private Set<ConnectionFolder> folderList; /** * Creates a new instance of ConnectionFolderManager. */ public ConnectionFolderManager() { this.root = new ConnectionFolder( "" ); //$NON-NLS-1$s this.root.setId( ROOT_ID ); //$NON-NLS-1$s this.folderList = new HashSet<ConnectionFolder>(); loadConnectionFolders(); ConnectionEventRegistry.addConnectionUpdateListener( this, ConnectionCorePlugin.getDefault().getEventRunner() ); this.folderList.add( this.root ); } /** * Gets the filename of the connection folder store. * * @return * the filename of the connection folder store */ public static final String getConnectionFolderStoreFileName() { String filename = ConnectionCorePlugin.getDefault().getStateLocation().append( CONNECTION_FOLDERS_FILENAME ) .toOSString(); return filename; } /** * Adds the ConnectionFolder to the connection folder list. If there is already a * connection folder with the same name the new connection folder is renamed. * * @param connectionFolder the connection folder */ public void addConnectionFolder( ConnectionFolder connectionFolder ) { if ( getConnectionFolderByName( connectionFolder.getName() ) != null ) { String newConnectionFolderName = Messages.bind( Messages.copy_n_of_s, "", connectionFolder.getName() ); //$NON-NLS-1$ for ( int i = 2; getConnectionFolderByName( newConnectionFolderName ) != null; i++ ) { newConnectionFolderName = Messages.bind( Messages.copy_n_of_s, i + " ", connectionFolder.getName() ); //$NON-NLS-1$ } connectionFolder.setName( newConnectionFolderName ); } folderList.add( connectionFolder ); ConnectionEventRegistry.fireConnectonFolderAdded( connectionFolder, this ); } /** * Removes the given ConnectionFolder from the connection folder list. * * @param connectionFolder * the connection folder to remove */ public void removeConnectionFolder( ConnectionFolder connectionFolder ) { folderList.remove( connectionFolder ); ConnectionEventRegistry.fireConnectonFolderRemoved( connectionFolder, this ); } /** * Gets an array of connection folders. * * @return * an array of connection folders */ public ConnectionFolder[] getConnectionFolders() { return folderList.toArray( new ConnectionFolder[0] ); } /** * Gets a connection folder from its id. * * @param id * the id of the connection folder * @return * the corresponding connection folder */ public ConnectionFolder getConnectionFolderById( String id ) { for ( ConnectionFolder folder : folderList ) { if ( folder.getId().equals( id ) ) { return folder; } } return null; } /** * Gets a connection folder from its name. * * @param name * the name of the connection folder * @return * the corresponding connection folder */ public ConnectionFolder getConnectionFolderByName( String name ) { for ( ConnectionFolder folder : folderList ) { if ( folder.getName().equals( name ) ) { return folder; } } return null; } /** * Gets the parent connection folder of the given connection. * * @param connection * the connection used to search the parent * @return * the parent connection folder of the given connection */ public ConnectionFolder getParentConnectionFolder( Connection connection ) { for ( ConnectionFolder folder : folderList ) { if ( folder.getConnectionIds().contains( connection.getId() ) ) { return folder; } } return getRootConnectionFolder(); } /** * Gets the parent connection folder of the given connection folder * or null if the folder doesn't have a parent folder. * * @param connectionFolder * the connection folder used to search the parent * @return * the parent connection folder of the given connection folder * or null if the folder doesn't have a parent folder */ public ConnectionFolder getParentConnectionFolder( ConnectionFolder connectionFolder ) { for ( ConnectionFolder folder : folderList ) { if ( folder.getSubFolderIds().contains( connectionFolder.getId() ) ) { return folder; } } return null; } /** * Gets the all sub-folders of the given folder including the given folder. * * @param folder the folder * * @return all sub-folders */ public Set<ConnectionFolder> getAllSubFolders( ConnectionFolder folder ) { Set<ConnectionFolder> allSubFolders = new HashSet<ConnectionFolder>(); List<String> ids = new ArrayList<String>(); ids.add( folder.getId() ); while ( !ids.isEmpty() ) { String id = ids.remove( 0 ); ConnectionFolder subFolder = getConnectionFolderById( id ); allSubFolders.add( subFolder ); ids.addAll( subFolder.getSubFolderIds() ); } return allSubFolders; } /** * Gets the all parent folders of the given folder including the given folder. * * @param folder the folder * * @return all parent folders */ public Set<ConnectionFolder> getAllParentFolders( ConnectionFolder folder ) { Set<ConnectionFolder> allParentFolders = new HashSet<ConnectionFolder>(); do { allParentFolders.add( folder ); folder = getParentConnectionFolder( folder ); } while ( folder != null ); return allParentFolders; } /** * Gets the root connection folder. * * @return the root connection folder */ public ConnectionFolder getRootConnectionFolder() { return root; } /** * Sets the root connection folder. * * @param root the new root connection folder */ public void setRootConnectionFolder( ConnectionFolder root ) { this.root = root; } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionAdded(org.apache.directory.studio.connection.core.Connection) */ public void connectionAdded( Connection connection ) { saveConnectionFolders(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionRemoved(org.apache.directory.studio.connection.core.Connection) */ public void connectionRemoved( Connection connection ) { saveConnectionFolders(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionUpdated(org.apache.directory.studio.connection.core.Connection) */ public void connectionUpdated( Connection connection ) { saveConnectionFolders(); } /** * @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 ) { saveConnectionFolders(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionFolderAdded(org.apache.directory.studio.connection.core.ConnectionFolder) */ public void connectionFolderAdded( ConnectionFolder connectionFolder ) { saveConnectionFolders(); } /** * @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionFolderRemoved(org.apache.directory.studio.connection.core.ConnectionFolder) */ public void connectionFolderRemoved( ConnectionFolder connectionFolder ) { saveConnectionFolders(); } /** * Saves the Connection Folders */ private synchronized void saveConnectionFolders() { // To avoid a corrupt file, save object to a temp file first try { ConnectionIO.saveConnectionFolders( folderList, new FileOutputStream( getConnectionFolderStoreFileName() + ConnectionManager.TEMP_SUFFIX ) ); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } // move temp file to good file File file = new File( getConnectionFolderStoreFileName() ); File tempFile = new File( getConnectionFolderStoreFileName() + ConnectionManager.TEMP_SUFFIX ); if ( file.exists() ) { file.delete(); } try { String content = FileUtils.readFileToString( tempFile, ConnectionManager.ENCODING_UTF8 ); FileUtils.writeStringToFile( file, content, ConnectionManager.ENCODING_UTF8 ); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Loads the Connection Folders */ private synchronized void loadConnectionFolders() { ConnectionEventRegistry.suspendEventFiringInCurrentThread(); try { folderList = ConnectionIO.loadConnectionFolders( new FileInputStream( getConnectionFolderStoreFileName() ) ); } catch ( Exception e ) { // If loading failed, try with temp file try { folderList = ConnectionIO.loadConnectionFolders( new FileInputStream( getConnectionFolderStoreFileName() + ConnectionManager.TEMP_SUFFIX ) ); } catch ( FileNotFoundException e1 ) { // TODO Auto-generated catch block } catch ( ConnectionIOException e1 ) { // TODO Auto-generated catch block } } if ( !folderList.isEmpty() ) { for ( ConnectionFolder folder : folderList ) { if ( ROOT_ID.equals( folder.getId() ) ) { root = folder; } } } else { Connection[] connections = ConnectionCorePlugin.getDefault().getConnectionManager().getConnections(); for ( Connection connection : connections ) { root.addConnectionId( connection.getId() ); } } ConnectionEventRegistry.resumeEventFiringInCurrentThread(); } }