/* * Copyright 2015 Amazon Technologies, Inc. * * Licensed 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://aws.amazon.com/apache2.0 * * This file 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 com.amazonaws.eclipse.core.accounts.profiles; import java.io.File; import java.io.FileFilter; import java.util.concurrent.ThreadFactory; import org.apache.commons.io.monitor.FileAlterationListener; import org.apache.commons.io.monitor.FileAlterationListenerAdaptor; import org.apache.commons.io.monitor.FileAlterationMonitor; import org.apache.commons.io.monitor.FileAlterationObserver; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import com.amazonaws.eclipse.core.AwsToolkitCore; import com.amazonaws.eclipse.core.preferences.PreferenceConstants; /** * Used to monitor a specific credentials file and prompts the user to reload * the credentials whenever the file content is changed. */ public class SdkCredentialsFileContentMonitor { private static final Log debugLogger = LogFactory.getLog(SdkCredentialsFileContentMonitor.class); private final static long DEFAULT_POLLING_INTERVAL_MILLIS = 3 * 1000; private final File _target; private final FileAlterationObserver _observer; private final FileAlterationMonitor _monitor; private final FileAlterationListener _listener; private boolean debugMode = false; public SdkCredentialsFileContentMonitor(File target) { this(target, DEFAULT_POLLING_INTERVAL_MILLIS); } public SdkCredentialsFileContentMonitor(File target, long pollingIntervalInMs) { this(target, pollingIntervalInMs, new FileAlterationListenerAdaptor() { @Override public void onFileChange(final File changedFile) { Display.getDefault().asyncExec(new Runnable() { public void run() { if (AwsToolkitCore.getDefault().getPreferenceStore() .getBoolean(PreferenceConstants.P_ALWAYS_RELOAD_WHEN_CREDNENTIAL_PROFILE_FILE_MODIFIED)) { AwsToolkitCore.getDefault().getAccountManager().reloadAccountInfo(); } else { showCredentialsReloadConfirmBox(changedFile); } } }); } }); } public SdkCredentialsFileContentMonitor( File target, long pollingIntervalInMillis, FileAlterationListener listener) { _target = target; // IllegalArgumentException is expected if target.getParentFile == null _observer = new FileAlterationObserver(target.getParentFile(), new FileFilter() { public boolean accept(File file) { return file.equals(_target); } }); _monitor = new FileAlterationMonitor(pollingIntervalInMillis); _listener = listener; _observer.addListener(_listener); _monitor.addObserver(_observer); // Use daemon thread to avoid thread leakage _monitor.setThreadFactory(new ThreadFactory() { public Thread newThread(Runnable runnable) { Thread t = new Thread(runnable); t.setDaemon(true); t.setName("aws-credentials-file-monitor-thread"); return t; } }); } public void start() { try { _monitor.start(); logInfo("Monitoring content of " + _target.getAbsolutePath()); } catch (Exception e) { logException("Unable to start file monitor on " + _target.getAbsolutePath(), e); } } public void stop() { try { _monitor.stop(); logInfo("Stopped monitoring content of " + _target.getAbsolutePath()); } catch (Exception e) { logException("Unable to stop the file monitor on " + _target.getAbsolutePath(), e); } } /** * Should only be invoked in the main thread */ private static void showCredentialsReloadConfirmBox(File credentialsFile) { String message = "The AWS credentials file '" + credentialsFile.getAbsolutePath() + "' has been changed in the file system. " + "Do you want to reload the credentials from the updated file content?"; MessageDialog dialog = new MessageDialog( null, // use the top-level shell "AWS Credentials File Changed", AwsToolkitCore.getDefault().getImageRegistry().get(AwsToolkitCore.IMAGE_AWS_ICON), message, MessageDialog.CONFIRM, new String[] { "No", "Yes", "Always Reload" }, 1 // default to YES ); int result = dialog.open(); if (result == 2) { AwsToolkitCore.getDefault().getPreferenceStore() .setValue( PreferenceConstants.P_ALWAYS_RELOAD_WHEN_CREDNENTIAL_PROFILE_FILE_MODIFIED, true); } if (result == 1 || result == 2) { AwsToolkitCore.getDefault().getAccountManager().reloadAccountInfo(); } } /** * For testing purpose only. */ public void setDebugMode(boolean debug) { this.debugMode = debug; } private void logInfo(String info) { if (debugMode) { debugLogger.debug(info); } else { AwsToolkitCore.getDefault().logInfo(info); } } private void logException(String msg, Exception e) { if (debugMode) { debugLogger.debug(msg, e); } else { AwsToolkitCore.getDefault().logException(msg, e); } } }