| /* |
| * 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$ |
| } |
| } |
| |
| } |