/*
 *    ALMA - Atacama Large Millimiter Array
 *    (c) European Southern Observatory, 2002
 *    Copyright by ESO (in the framework of the ALMA collaboration),
 *    All rights reserved
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 *    MA 02111-1307  USA
 */
package alma.jconttest.DummyComponentImpl;

import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import alma.acs.component.ComponentImplBase;
import alma.acs.logging.ClientLogManager;
import alma.jconttest.DummyComponentOperations;
import alma.maciErrType.wrappers.AcsJComponentCleanUpEx;

/**
 * @author hsommer
 * created Nov 12, 2003 6:47:00 PM
 */
public class DummyComponentImpl extends ComponentImplBase implements DummyComponentOperations
{
	// super.m_logger is not reliable because no container services may be set during some special test execution.
	// Only access this field through methods getLogger().
	private Logger myLogger;
	
	/** 
	 * Logs a message, which should facilitate debugging the logs when the synchronization of deactivation with long-running methods is being tested.
	 */
	public void cleanUp() throws AcsJComponentCleanUpEx {
		getLogger().info("cleanUp called.");
		super.cleanUp();
	}

	
	
	/**
	 * @see alma.jconttest.DummyComponentOperations#dymmyComponentsCanDoCloseToNothing()
	 */
	public void dummyComponentsCanDoCloseToNothing()
	{
		// or actually nothing
	}

	public void callThatTakesSomeTime(int timeInMillisec) {
		if (timeInMillisec > 0) {
			getLogger().info("Called in thread " + Thread.currentThread().getName() + ". Will sleep for " + timeInMillisec + " millisec");
			long sleepTimeBeginNano = System.nanoTime();
			try {
				// This "fancy" sleep in a loop is supposed to guarantee that we don't wake up too early, 
				// which may have been the cause for spurious failures in the test method AcsCorbaTestWithContainer#testComponentPOALifecycleAsync
				while (System.nanoTime() < sleepTimeBeginNano + TimeUnit.MILLISECONDS.toNanos(timeInMillisec)) {
					Thread.sleep(timeInMillisec);
				}
			} catch (InterruptedException e) {
				long wakeTimeNano = System.nanoTime();
				String msg = "Sleep was interrupted after just " + TimeUnit.NANOSECONDS.toMillis(wakeTimeNano - sleepTimeBeginNano) + " ms instead of " + timeInMillisec + " ms.";
				getLogger().warning(msg);
				throw new org.omg.CORBA.UNKNOWN(msg);
			}
		}
		getLogger().info("slept enough.");
	}

	/**
	 * Gets a logger, even if this component does not run inside a container and thus no ContainerServices are provided.
	 * This is a special hack for this test component which should never be used for any real components.
	 */
	private Logger getLogger() {
		if (myLogger == null) {
			if (m_logger != null) {
				myLogger = m_logger;
			}
			else {
				myLogger = ClientLogManager.getAcsLogManager().getLoggerForApplication("DummyComponentImpl running outside of container", false);
			}
		}
		return myLogger;
	}
}

@@ -2346,16 +2346,111 @@
 Time();%0A
+%09%09%09long sleepTimeEndNano = sleepTimeBeginNano + TimeUnit.MILLISECONDS.toNanos(timeInMillisec);%0A
 %09%09%09try %7B
@@ -2450,16 +2450,16 @@
 %09%09try %7B%0A
-
 %09%09%09%09// T
@@ -2688,15 +2688,62 @@
 %09%09%09%09
-while (
+long currentTimeNano = 0;%0A%09%09%09%09while ((currentTimeNano=
 Syst
@@ -2755,16 +2755,17 @@
 noTime()
+)
  %3C sleep
@@ -2764,36 +2764,53 @@
  %3C sleepTime
-BeginNano + 
+EndNano) %7B%0A%09%09%09%09%09Thread.sleep(
 TimeUnit.MIL
@@ -2798,37 +2798,36 @@
 .sleep(TimeUnit.
-MILLI
+NANO
 SECONDS.toNanos(
@@ -2824,65 +2824,50 @@
 S.to
-Nanos(timeInMillisec)) %7B%0A%09%09%09%09%09Thread.
+Millis(
 sleep
-(timeInMillisec
+TimeEndNano - currentTimeNano)
 );%0A%09

Fix of yesterday's change: Now sleeps only the remaining time after waiting up too early, not the full sleep time again.