/* * 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.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor; import org.apache.directory.studio.common.ui.CommonUIUtils; import org.apache.directory.studio.ldapservers.model.LdapServer; import org.apache.directory.studio.ldapservers.model.LdapServerStatus; import org.apache.mina.util.AvailablePortFinder; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.RuntimeProcess; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.console.MessageConsole; import org.osgi.framework.Bundle; /** * The helper class defines various utility methods for the LDAP Servers plugin. */ public class LdapServersUtils { /** The ID of the launch configuration custom object */ public static final String LAUNCH_CONFIGURATION_CUSTOM_OBJECT = "launchConfiguration"; //$NON-NLS-1$ /** The ID of the console printer custom object */ public static final String CONSOLE_PRINTER_CUSTOM_OBJECT = "consolePrinter"; //$NON-NLS-1$ /** * Runs the startup listener watchdog. * * @param server * the server * @param port * the port * @throws Exception */ public static void runStartupListenerWatchdog( LdapServer server, int port ) throws Exception { // If no protocol is enabled, we pass this and declare the server as started if ( port == 0 ) { return; } // Getting the current time long startTime = System.currentTimeMillis(); // Calculating the watch dog time final long watchDog = startTime + ( 1000 * 60 * 3 ); // 3 minutes // Looping until the end of the watchdog if the server is still 'starting' while ( ( System.currentTimeMillis() < watchDog ) && ( LdapServerStatus.STARTING == server.getStatus() ) ) { // Trying to see if the port is available if ( AvailablePortFinder.available( port ) ) { // The port is still available // We just wait one second before starting the test once again try { Thread.sleep( 1000 ); } catch ( InterruptedException e1 ) { // Nothing to do... } } else { // We set the state of the server to 'started'... server.setStatus( LdapServerStatus.STARTED ); // ... and we exit the thread return; } } // If, at the end of the watch dog, the state of the server is // still 'starting' then, we declare the server as 'stopped' if ( LdapServerStatus.STARTING == server.getStatus() ) { server.setStatus( LdapServerStatus.STOPPED ); } } /** * Starting the "terminate" listener thread. * * @param server * the server * @param launch * the launch */ public static void startTerminateListenerThread( final LdapServer server, final ILaunch launch ) { // Creating the thread Thread thread = new Thread() { public void run() { // Adding the listener DebugPlugin.getDefault().addDebugEventListener( new IDebugEventSetListener() { public void handleDebugEvents( DebugEvent[] events ) { // Looping on the debug events array for ( DebugEvent debugEvent : events ) { // We only care of event with kind equals to // 'terminate' if ( debugEvent.getKind() == DebugEvent.TERMINATE ) { // Getting the source of the debug event Object source = debugEvent.getSource(); if ( source instanceof RuntimeProcess ) { RuntimeProcess runtimeProcess = ( RuntimeProcess ) source; // Getting the associated launch ILaunch debugEventLaunch = runtimeProcess.getLaunch(); if ( debugEventLaunch.equals( launch ) ) { // The launch we had created is now terminated // The server is now stopped server.setStatus( LdapServerStatus.STOPPED ); // Removing the listener DebugPlugin.getDefault().removeDebugEventListener( this ); // ... and we exit the thread return; } } } } } } ); } }; // Starting the thread thread.start(); } /** * Starts the console printer thread. * * @param server * the server * @param serverLogsFile * the server logs file */ public static void startConsolePrinterThread( LdapServer server, File serverLogsFile ) { MessageConsole messageConsole = ConsolesManager.getDefault().getMessageConsole( server ); ConsolePrinterThread consolePrinter = new ConsolePrinterThread( serverLogsFile, messageConsole.newMessageStream() ); consolePrinter.start(); // Storing the console printer as a custom object in the LDAP Server for later use server.putCustomObject( CONSOLE_PRINTER_CUSTOM_OBJECT, consolePrinter ); } /** * Stops the console printer thread. * * @param server * the server */ public static void stopConsolePrinterThread( LdapServer server ) { // Getting the console printer ConsolePrinterThread consolePrinter = ( ConsolePrinterThread ) server .removeCustomObject( CONSOLE_PRINTER_CUSTOM_OBJECT ); if ( ( consolePrinter != null ) && ( consolePrinter.isAlive() ) ) { // Closing the console printer consolePrinter.close(); } } /** * Terminates the launch configuration. * * @param server * the server * @throws Exception */ public static void terminateLaunchConfiguration( LdapServer server ) throws Exception { // Getting the launch ILaunch launch = ( ILaunch ) server.removeCustomObject( LdapServersUtils.LAUNCH_CONFIGURATION_CUSTOM_OBJECT ); if ( ( launch != null ) && ( !launch.isTerminated() ) ) { // Terminating the launch launch.terminate(); } else { throw new Exception( Messages.getString( "LdapServersUtils.AssociatedLaunchConfigurationCouldNotBeFoundOrTerminated" ) ); //$NON-NLS-1$ } } /** * Verifies that the libraries folder exists and contains the jar files * needed to launch the server. * * @param bundle * the bundle * @param sourceLibrariesPath * the path to the source libraries * @param destinationLibrariesPath * the path to the destination libraries * @param libraries * the names of the libraries */ private static void verifyAndCopyLibraries( Bundle bundle, IPath sourceLibrariesPath, IPath destinationLibrariesPath, String[] libraries ) { // Destination libraries folder File destinationLibraries = destinationLibrariesPath.toFile(); if ( !destinationLibraries.exists() ) { destinationLibraries.mkdir(); } // Verifying and copying libraries (if needed) for ( String library : libraries ) { File destinationLibraryFile = destinationLibrariesPath.append( library ).toFile(); boolean newerFileExists = (bundle.getLastModified() > destinationLibraryFile.lastModified()); if ( !destinationLibraryFile.exists() || newerFileExists ) { try { copyResource( bundle, sourceLibrariesPath.append( library ), destinationLibraryFile ); } catch ( IOException e ) { CommonUIUtils.openErrorDialog( NLS.bind( Messages.getString( "LdapServersUtils.ErrorCopyingLibrary" ), //$NON-NLS-1$ new String[] { library, destinationLibraryFile.getAbsolutePath(), e.getMessage() } ) ); } } } } /** * Verifies that the libraries folder exists and contains the jar files * needed to launch the server. * * @param bundle * the bundle * @param sourceLibrariesPath * the path to the source libraries * @param destinationLibrariesPath * the path to the destination libraries * @param libraries * the names of the libraries * @param monitor the monitor * @param monitorTaskName the name of the task for the monitor */ public static void verifyAndCopyLibraries( Bundle bundle, IPath sourceLibrariesPath, IPath destinationLibrariesPath, String[] libraries, StudioProgressMonitor monitor, String monitorTaskName ) { // Creating the sub-task on the monitor monitor.subTask( monitorTaskName ); // Verifying and copying the libraries verifyAndCopyLibraries( bundle, sourceLibrariesPath, destinationLibrariesPath, libraries ); } /** * Copy the given resource. * * @param bundle * the bundle * @param resource * the path of the resource * @param destination * the destination * @throws IOException * if an error occurs when copying the jar file */ public static void copyResource( Bundle bundle, IPath resource, File destination ) throws IOException { // Getting he URL of the resource within the bundle URL resourceUrl = FileLocator.find( bundle, resource, null ); // Creating the input and output streams InputStream resourceInputStream = resourceUrl.openStream(); FileOutputStream resourceOutputStream = new FileOutputStream( destination ); // Copying the resource copyFile( resourceInputStream, resourceOutputStream ); // Closing the streams resourceInputStream.close(); resourceOutputStream.close(); } /** * Copies a file from the given streams. * * @param inputStream * the input stream * @param outputStream * the output stream * @throws IOException * if an error occurs when copying the file */ private static void copyFile( InputStream inputStream, OutputStream outputStream ) throws IOException { byte[] buf = new byte[1024]; int i = 0; while ( ( i = inputStream.read( buf ) ) != -1 ) { outputStream.write( buf, 0, i ); } } }