/******************************************************************************* * Copyright (c) 2008, 2011 Thomas Holland (thomas@innot.de) and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Thomas Holland - initial API and implementation *******************************************************************************/ package de.innot.avreclipse.core.paths; import java.io.File; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.preference.IPreferenceStore; import de.innot.avreclipse.core.preferences.AVRPathsPreferences; public class AVRPathManager implements IPathProvider { public enum SourceType { Bundled, System, Custom } private IPreferenceStore fPrefs; private final AVRPath fAvrPath; private String fPrefsValue = null; /** * Creates a PathProvider for the instance Preference Store and AVRPath. * */ public AVRPathManager(AVRPath avrpath) { this(AVRPathsPreferences.getPreferenceStore(), avrpath); } /** * Creates a PathProvider for the given Preference Store and AVRPath. * */ public AVRPathManager(IPreferenceStore store, AVRPath avrpath) { fPrefs = store; fAvrPath = avrpath; } /** * Creates a copy of the given AVRPathManager. * * @param pathmanager */ public AVRPathManager(AVRPathManager pathmanager) { this(pathmanager.fPrefs, pathmanager.fAvrPath); fPrefsValue = pathmanager.fPrefsValue; } /** * Gets the UI name of the underlying AVRPath. * * @return String with the name */ public String getName() { return fAvrPath.toString(); } /** * Gets a description from the underlying AVRPath. * * @return String with the description of the path */ public String getDescription() { return fAvrPath.getDescription(); } /** * Gets the current path. * * This is different from IPathProvider.getPath() because the returned path is cached internally * and can be modified with the setPath() method. * * * @return <code>IPath</code> */ public IPath getPath() { // get the path from the preferences store and returns its value, // depending on the selected path source if (fPrefsValue == null) { fPrefsValue = fPrefs.getString(fAvrPath.name()); } if (fPrefsValue.equals(AVRPathManager.SourceType.System.name())) { // System path return getSystemPath(false); } if (fPrefsValue.startsWith(AVRPathManager.SourceType.Bundled.name())) { // Bundle path String bundleid = fPrefsValue.substring(fPrefsValue.indexOf(':') + 1); return getBundlePath(bundleid); } // else: a custom path IPath path = new Path(fPrefsValue); return path; } /** * Gets the default path. * * @return <code>IPath</code> to the default source directory */ public IPath getDefaultPath() { // Don't want to duplicate the parsing done in getPath() so // just set the current value to the default, call getPath and // restore the current value afterward. String defaultvalue = fPrefs.getDefaultString(fAvrPath.name()); String oldPrefsValue = fPrefsValue; fPrefsValue = defaultvalue; IPath defaultpath = getPath(); fPrefsValue = oldPrefsValue; return defaultpath; } /** * Gets the system path. * * This is the path as determined by system path / windows registry. * * @param force * If <code>true</code> reload the system path directly, without using any cached * values. * * @return <code>IPath</code> to the system dependent source directory */ public IPath getSystemPath(boolean force) { return SystemPathHelper.getPath(fAvrPath, force); } /** * Gets the path from the Eclipse bundle with the given id. * * @param bundleid * ID of the source bundle * @return <code>IPath</code> to the source directory within the bundle. */ public IPath getBundlePath(String bundleid) { return BundlePathHelper.getPath(fAvrPath, bundleid); } /** * Sets the path in the preference store. * * @param newpath * @param context */ public void setPath(String newpath, SourceType source) { String newvalue = null; switch (source) { case System: newvalue = source.name(); break; case Bundled: newvalue = source.name() + ":" + newpath; break; case Custom: newvalue = newpath; } fPrefsValue = newvalue; } /** * Sets the path back to the default value. */ public void setToDefault() { fPrefsValue = fPrefs.getDefaultString(fAvrPath.name()); } /** * Gets the source of this path. * * This can be one of the {@link SourceType} values * <ul> * <li><code>Bundled</code> if the path points to a bundled avr-gcc toolchain.</li> * <li><code>System</code> if the system default path is used.</li> * <li><code>Custom</code> if the path is selected by the user.</li> * </ul> * * @return */ public AVRPathManager.SourceType getSourceType() { if (fPrefsValue == null) { // get the path source from the preferences store fPrefsValue = fPrefs.getString(fAvrPath.name()); } if (fPrefsValue.equals(AVRPathManager.SourceType.System.name())) { return AVRPathManager.SourceType.System; } if (fPrefsValue.startsWith(AVRPathManager.SourceType.Bundled.name())) { return AVRPathManager.SourceType.Bundled; } // else: a custom path return AVRPathManager.SourceType.Custom; } /** * Checks if the path managed by this manager is optional. * * @return <code>true</code> if path is not required for basic plugin operation. */ public boolean isOptional() { return fAvrPath.isOptional(); } /** * Checks if the current path is valid. * <p> * Some paths are required, some are optional. * </p> * <p> * For required paths this method returns <code>true</code> if a internally defined testfile * exists in the given path. * </p> * <p> * For optional paths this method also returns true if - and only if - the path is empty (""). * </p> * * @return <code>true</code> if the path points to a valid source folder. */ public boolean isValid() { IPath path = getPath(); // Test if the file is optional. If optional, // then an empty Path is also valid if (fAvrPath.isOptional()) { if (path.isEmpty()) { return true; } } // Test if the testfile exists in the given folder IPath testpath = path.append(fAvrPath.getTest()); File file = testpath.toFile(); if (file.canRead()) { return true; } // try with ".exe" appended, as otherwise on Windows // file.canRead() will fail testpath = path.append(fAvrPath.getTest() + ".exe"); file = testpath.toFile(); if (file.canRead()) { return true; } return false; } /** * Sets the PreferenceStore the PathManager should work on. * * By default the PathManager will work on the Instance Preference store. * * @param store */ public void setPreferenceStore(IPreferenceStore store) { fPrefs = store; } /** * Stores the path in the PreferenceStore. * * Until <code>store()</code> is called, all modifications to the path are only internal to * this IPathManager and not visible outside. */ public void store() { if (fPrefsValue != null) { fPrefs.setValue(fAvrPath.name(), fPrefsValue); } } }