blob: ab81e6305f8d1f4b157e73bb1b21ad70a469f7e8 [file] [log] [blame]
/*
* 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.ldapbrowser.core;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.apache.directory.api.util.FileUtils;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
import org.apache.directory.studio.connection.core.ConnectionFolder;
import org.apache.directory.studio.connection.core.Utils;
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.ConnectionIOException;
import org.apache.directory.studio.ldapbrowser.core.events.BookmarkUpdateEvent;
import org.apache.directory.studio.ldapbrowser.core.events.BookmarkUpdateListener;
import org.apache.directory.studio.ldapbrowser.core.events.BrowserConnectionUpdateEvent;
import org.apache.directory.studio.ldapbrowser.core.events.BrowserConnectionUpdateListener;
import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
import org.apache.directory.studio.ldapbrowser.core.events.SearchUpdateEvent;
import org.apache.directory.studio.ldapbrowser.core.events.SearchUpdateListener;
import org.apache.directory.studio.ldapbrowser.core.model.BookmarkParameter;
import org.apache.directory.studio.ldapbrowser.core.model.IBookmark;
import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.ISearch;
import org.apache.directory.studio.ldapbrowser.core.model.SearchParameter;
import org.apache.directory.studio.ldapbrowser.core.model.impl.Bookmark;
import org.apache.directory.studio.ldapbrowser.core.model.impl.BrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.impl.Search;
import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
/**
* This class is used to manage {@link IBrowserConnection}s.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class BrowserConnectionManager implements ConnectionUpdateListener, BrowserConnectionUpdateListener,
SearchUpdateListener, BookmarkUpdateListener
{
/** The list of connections. */
private Map<String, IBrowserConnection> connectionMap;
/**
* Creates a new instance of ConnectionManager.
*/
public BrowserConnectionManager()
{
this.connectionMap = new HashMap<String, IBrowserConnection>();
// no need to fire events while loading connections
EventRegistry.suspendEventFiringInCurrentThread();
loadBrowserConnections();
EventRegistry.resumeEventFiringInCurrentThread();
ConnectionEventRegistry.addConnectionUpdateListener( this, ConnectionCorePlugin.getDefault().getEventRunner() );
EventRegistry.addSearchUpdateListener( this, BrowserCorePlugin.getDefault().getEventRunner() );
EventRegistry.addBookmarkUpdateListener( this, BrowserCorePlugin.getDefault().getEventRunner() );
EventRegistry.addBrowserConnectionUpdateListener( this, BrowserCorePlugin.getDefault().getEventRunner() );
}
/**
* Gets the Schema Cache filename for the corresponding browser connection.
*
* @param browserConnection
* the browser connection
* @return
* the Schema Cache filename for the corresponding browser connection
*/
public static final String getSchemaCacheFileName( String id )
{
return BrowserCorePlugin.getDefault().getStateLocation().append(
"schema-" + Utils.getFilenameString( id ) + ".ldif" ).toOSString(); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the filename of the Connection Store.
*
* @return
* the filename of the Connection Store
*/
public static final String getBrowserConnectionStoreFileName()
{
String filename = BrowserCorePlugin.getDefault().getStateLocation()
.append( "browserconnections.xml" ).toOSString(); //$NON-NLS-1$
File file = new File( filename );
if ( !file.exists() )
{
// try to convert old connections.xml:
// 1st search it in current workspace with the old ldapstudio plugin ID
// 2nd search it in old .ldapstudio workspace with the old ldapstudio plugin ID
String[] oldFilenames = new String[2];
oldFilenames[0] = filename.replace( "org.apache.directory.studio.ldapbrowser.core", //$NON-NLS-1$
"org.apache.directory.ldapstudio.browser.core" ); //$NON-NLS-1$
oldFilenames[1] = oldFilenames[0].replace( ".ApacheDirectoryStudio", ".ldapstudio" ); //$NON-NLS-1$ //$NON-NLS-2$
for ( int i = 0; i < oldFilenames.length; i++ )
{
File oldFile = new File( oldFilenames[i] );
if ( oldFile.exists() )
{
try
{
String oldContent = FileUtils.readFileToString( oldFile, "UTF-8" ); //$NON-NLS-1$
String newContent = oldContent.replace( "org.apache.directory.ldapstudio.browser.core", //$NON-NLS-1$
"org.apache.directory.studio.ldapbrowser.core" ); //$NON-NLS-1$
FileUtils.writeStringToFile( file, newContent, "UTF-8" ); //$NON-NLS-1$
break;
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
}
return filename;
}
/**
* Gets a browser connection from its id.
*
* @param id
* the id of the Connection
* @return
* the corresponding IBrowserConnection
*/
public IBrowserConnection getBrowserConnectionById( String id )
{
return connectionMap.get( id );
}
/**
* Gets a browser connection from its name.
*
* @param name
* the name of the Connection
* @return
* the corresponding IBrowserConnection
*/
public IBrowserConnection getBrowserConnectionByName( String name )
{
Connection connection = ConnectionCorePlugin.getDefault().getConnectionManager().getConnectionByName( name );
return getBrowserConnection( connection );
}
/**
* Gets a browser connection from its underlying connection.
*
* @param connection
* the underlying connection
* @return
* the corresponding IBrowserConnection
*/
public IBrowserConnection getBrowserConnection( Connection connection )
{
return connection != null ? getBrowserConnectionById( connection.getId() ) : null;
}
/**
* Gets an array containing all the Connections.
*
* @return
* an array containing all the Connections
*/
public IBrowserConnection[] getBrowserConnections()
{
return ( IBrowserConnection[] ) connectionMap.values().toArray( new IBrowserConnection[0] );
}
/**
* @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionRemoved(org.apache.directory.studio.connection.core.Connection)
*/
public void connectionRemoved( Connection connection )
{
// update connection list
connectionMap.remove( connection.getId() );
// remove schema file
File schemaFile = new File( getSchemaCacheFileName( connection.getId() ) );
if ( schemaFile.exists() )
{
schemaFile.delete();
}
// make persistent
saveBrowserConnections();
}
/**
* @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionAdded(org.apache.directory.studio.connection.core.Connection)
*/
public void connectionAdded( Connection connection )
{
// update connection list
BrowserConnection browserConnection = new BrowserConnection( connection );
connectionMap.put( connection.getId(), browserConnection );
// make persistent
saveBrowserConnections();
}
/**
* @see org.apache.directory.studio.connection.core.event.ConnectionUpdateListener#connectionUpdated(org.apache.directory.studio.connection.core.Connection)
*/
public void connectionUpdated( Connection connection )
{
saveBrowserConnections();
saveSchema( getBrowserConnection( connection ) );
}
/**
* @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 )
{
}
/**
* @see org.apache.directory.studio.ldapbrowser.core.events.BrowserConnectionUpdateListener#browserConnectionUpdated(org.apache.directory.studio.ldapbrowser.core.events.BrowserConnectionUpdateEvent)
*/
public void browserConnectionUpdated( BrowserConnectionUpdateEvent browserConnectionUpdateEvent )
{
if ( browserConnectionUpdateEvent.getDetail() == BrowserConnectionUpdateEvent.Detail.SCHEMA_UPDATED )
{
saveSchema( browserConnectionUpdateEvent.getBrowserConnection() );
}
}
/**
* {@inheritDoc}
*/
public void searchUpdated( SearchUpdateEvent searchUpdateEvent )
{
if ( searchUpdateEvent.getDetail() == SearchUpdateEvent.EventDetail.SEARCH_ADDED
|| searchUpdateEvent.getDetail() == SearchUpdateEvent.EventDetail.SEARCH_REMOVED
|| searchUpdateEvent.getDetail() == SearchUpdateEvent.EventDetail.SEARCH_RENAMED
|| searchUpdateEvent.getDetail() == SearchUpdateEvent.EventDetail.SEARCH_PARAMETER_UPDATED )
{
saveBrowserConnections();
}
}
/**
* {@inheritDoc}
*/
public void bookmarkUpdated( BookmarkUpdateEvent bookmarkUpdateEvent )
{
if ( bookmarkUpdateEvent.getDetail() == BookmarkUpdateEvent.Detail.BOOKMARK_ADDED
|| bookmarkUpdateEvent.getDetail() == BookmarkUpdateEvent.Detail.BOOKMARK_REMOVED
|| bookmarkUpdateEvent.getDetail() == BookmarkUpdateEvent.Detail.BOOKMARK_UPDATED )
{
saveBrowserConnections();
}
}
/**
* Saves the browser Connections
*/
private void saveBrowserConnections()
{
// To avoid a corrupt file, save object to a temp file first
try
{
BrowserConnectionIO.save( new FileOutputStream( getBrowserConnectionStoreFileName() + "-temp" ), //$NON-NLS-1$
connectionMap );
}
catch ( IOException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// move temp file to good file
File file = new File( getBrowserConnectionStoreFileName() );
File tempFile = new File( getBrowserConnectionStoreFileName() + "-temp" ); //$NON-NLS-1$
if ( file.exists() )
{
file.delete();
}
try
{
String content = FileUtils.readFileToString( tempFile, "UTF-8" ); //$NON-NLS-1$
FileUtils.writeStringToFile( file, content, "UTF-8" ); //$NON-NLS-1$
}
catch ( IOException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// Object[][] object = new Object[connectionMap.size()][3];
//
// Iterator<IBrowserConnection> connectionIterator = connectionMap.values().iterator();
// for ( int i = 0; connectionIterator.hasNext(); i++ )
// {
// IBrowserConnection browserConnection = connectionIterator.next();
//
// ISearch[] searches = browserConnection.getSearchManager().getSearches();
// SearchParameter[] searchParameters = new SearchParameter[searches.length];
// for ( int k = 0; k < searches.length; k++ )
// {
// searchParameters[k] = searches[k].getSearchParameter();
// }
//
// IBookmark[] bookmarks = browserConnection.getBookmarkManager().getBookmarks();
// BookmarkParameter[] bookmarkParameters = new BookmarkParameter[bookmarks.length];
// for ( int k = 0; k < bookmarks.length; k++ )
// {
// bookmarkParameters[k] = bookmarks[k].getBookmarkParameter();
// }
//
// object[i][0] = browserConnection.getConnection().getId();
// object[i][1] = searchParameters;
// object[i][2] = bookmarkParameters;
// }
//
// save( object, getBrowserConnectionStoreFileName() );
}
/**
* Saves the Schema of the Connection
*
* @param browserConnection
* the Connection
*/
private void saveSchema( IBrowserConnection browserConnection )
{
if ( browserConnection == null )
{
return;
}
try
{
String filename = getSchemaCacheFileName( browserConnection.getConnection().getId() );
FileWriter writer = new FileWriter( filename );
browserConnection.getSchema().saveToLdif( writer );
writer.close();
}
catch ( Exception e )
{
e.printStackTrace();
}
}
/**
* Loads the Connections
*/
private void loadBrowserConnections()
{
Connection[] connections = ConnectionCorePlugin.getDefault().getConnectionManager().getConnections();
for ( int i = 0; i < connections.length; i++ )
{
Connection connection = connections[i];
BrowserConnection browserConnection = new BrowserConnection( connection );
connectionMap.put( connection.getId(), browserConnection );
try
{
String schemaFilename = getSchemaCacheFileName( connection.getId() );
FileReader reader = new FileReader( schemaFilename );
Schema schema = new Schema();
schema.loadFromLdif( reader );
browserConnection.setSchema( schema );
}
catch ( Exception e )
{
}
}
// java.beans.XMLDecoder
try
{
String fileName = getBrowserConnectionStoreFileName();
File file = new File( fileName );
if ( file.exists() )
{
String oldContent = FileUtils.readFileToString( file, "UTF-8" ); //$NON-NLS-1$
if ( !oldContent.contains( "java.beans.XMLDecoder" ) ) //$NON-NLS-1$
{
// new file format
try
{
BrowserConnectionIO.load( new FileInputStream( getBrowserConnectionStoreFileName() ),
connectionMap );
}
catch ( Exception e )
{
// If loading failed, try with temp file
try
{
BrowserConnectionIO.load( new FileInputStream( getBrowserConnectionStoreFileName()
+ "-temp" ), connectionMap ); //$NON-NLS-1$
}
catch ( FileNotFoundException e1 )
{
// TODO Auto-generated catch block
return;
}
catch ( ConnectionIOException e1 )
{
// TODO Auto-generated catch block
return;
}
}
}
else
{
// old file format
Object[][] object = ( Object[][] ) this.load( getBrowserConnectionStoreFileName() );
if ( object != null )
{
try
{
for ( int i = 0; i < object.length; i++ )
{
String connectionId = ( String ) object[i][0];
IBrowserConnection browserConnection = getBrowserConnectionById( connectionId );
if ( browserConnection != null )
{
if ( object[i].length > 0 )
{
SearchParameter[] searchParameters = ( SearchParameter[] ) object[i][1];
for ( int k = 0; k < searchParameters.length; k++ )
{
ISearch search = new Search( browserConnection, searchParameters[k] );
browserConnection.getSearchManager().addSearch( search );
}
}
if ( object[i].length > 1 )
{
BookmarkParameter[] bookmarkParameters = ( BookmarkParameter[] ) object[i][2];
for ( int k = 0; k < bookmarkParameters.length; k++ )
{
IBookmark bookmark = new Bookmark( browserConnection, bookmarkParameters[k] );
browserConnection.getBookmarkManager().addBookmark( bookmark );
}
}
}
}
}
catch ( ArrayIndexOutOfBoundsException e )
{
// Thrown by decoder.readObject(), signals EOF
}
catch ( Exception e )
{
e.printStackTrace();
}
}
}
}
}
catch ( Exception e )
{
}
}
/**
* Loads an Object from an XML file
*
* @param filename
* the filename of the XML file
* @return
* the deserialized Object
*/
private synchronized Object load( String filename )
{
try
{
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
XMLDecoder decoder = new XMLDecoder( new BufferedInputStream( ( new FileInputStream( filename ) ) ) );
Object object = decoder.readObject();
decoder.close();
return object;
}
catch ( IOException ioe )
{
return null;
}
catch ( Exception e )
{
// if loading failed, try with temp file
String tempFilename = filename + "-temp"; //$NON-NLS-1$
try
{
XMLDecoder decoder = new XMLDecoder( new BufferedInputStream( ( new FileInputStream( tempFilename ) ) ) );
Object object = decoder.readObject();
decoder.close();
return object;
}
catch ( IOException ioe2 )
{
return null;
}
catch ( Exception e2 )
{
return null;
}
}
}
class TypeSafeEnumPersistenceDelegate extends PersistenceDelegate
{
protected boolean mutatesTo( Object oldInstance, Object newInstance )
{
return oldInstance == newInstance;
}
protected Expression instantiate( Object oldInstance, Encoder out )
{
Class<?> type = oldInstance.getClass();
if ( !Modifier.isPublic( type.getModifiers() ) )
{
throw new IllegalArgumentException( "Could not instantiate instance of non-public class: " //$NON-NLS-1$
+ oldInstance );
}
for ( Field field : type.getFields() )
{
int mod = field.getModifiers();
if ( Modifier.isPublic( mod ) && Modifier.isStatic( mod ) && Modifier.isFinal( mod )
&& ( type == field.getDeclaringClass() ) )
{
try
{
if ( oldInstance == field.get( null ) )
{
return new Expression( oldInstance, field, "get", new Object[] //$NON-NLS-1$
{ null } );
}
}
catch ( IllegalAccessException exception )
{
throw new IllegalArgumentException( "Could not get value of the field: " + field, exception ); //$NON-NLS-1$
}
}
}
throw new IllegalArgumentException( "Could not instantiate value: " + oldInstance ); //$NON-NLS-1$
}
}
}