Java tutorial
/* * 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.commons.io.input.Tailer; import org.apache.commons.io.input.TailerListener; import org.apache.commons.io.input.TailerListenerAdapter; 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.eclipse.ui.console.MessageConsoleStream; 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); MessageConsoleStream messageStream = messageConsole.newMessageStream(); /* * DIRSTUDIO-1148: Tail the log file and update the console. * Tail from end only to avoid overwhelming the system in case the log file is large. */ TailerListener l = new TailerListenerAdapter() { public void handle(String line) { messageStream.println(line); }; }; Tailer tailer = Tailer.create(serverLogsFile, l, 1000L, true); // Storing the tailer as a custom object in the LDAP Server for later use server.putCustomObject(CONSOLE_PRINTER_CUSTOM_OBJECT, tailer); } /** * Stops the tailer thread. * * @param server * the server */ public static void stopConsolePrinterThread(LdapServer server) { // Getting the console printer Tailer tailer = (Tailer) server.removeCustomObject(CONSOLE_PRINTER_CUSTOM_OBJECT); if (tailer != null) { // Closing the console printer tailer.stop(); } } /** * 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) { if ((!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); } } }