Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.adt.internal;
     18 
     19 import com.android.SdkConstants;
     20 import com.android.ide.eclipse.adt.AdtPlugin;
     21 import com.android.ide.eclipse.adt.AdtPlugin.CheckSdkErrorHandler;
     22 import com.android.ide.eclipse.adt.AdtPlugin.CheckSdkErrorHandler.Solution;
     23 import com.android.ide.eclipse.adt.Messages;
     24 import com.android.sdklib.repository.FullRevision;
     25 import com.android.sdklib.repository.FullRevision.PreviewComparison;
     26 import com.android.sdklib.repository.PkgProps;
     27 
     28 import org.osgi.framework.Constants;
     29 import org.osgi.framework.Version;
     30 
     31 import java.io.BufferedReader;
     32 import java.io.File;
     33 import java.io.FileNotFoundException;
     34 import java.io.FileReader;
     35 import java.io.IOException;
     36 import java.util.regex.Matcher;
     37 import java.util.regex.Pattern;
     38 
     39 /**
     40  * Class handling the version check for the plugin vs. the SDK.<br>
     41  * The plugin must be able to support all version of the SDK.
     42  *
     43  * <p/>An SDK can require a new version of the plugin.
     44  * <p/>The SDK contains a file with the minimum version for the plugin. This file is inside the
     45  * <code>tools/lib</code> directory, and is called <code>plugin.prop</code>.<br>
     46  * Inside that text file, there is a line in the format "plugin.version=#.#.#". This is checked
     47  * against the current plugin version.<br>
     48  *
     49  */
     50 public final class VersionCheck {
     51     /**
     52      * The minimum version of the SDK Tools that this version of ADT requires.
     53      */
     54     private final static FullRevision MIN_TOOLS_REV = new FullRevision(24, 0, 2, 0);
     55 
     56     /**
     57      * Pattern to get the minimum plugin version supported by the SDK. This is read from
     58      * the file <code>$SDK/tools/lib/plugin.prop</code>.
     59      */
     60     private final static Pattern sPluginVersionPattern = Pattern.compile(
     61             "^plugin.version=(\\d+)\\.(\\d+)\\.(\\d+).*$"); //$NON-NLS-1$
     62     private final static Pattern sSourcePropPattern = Pattern.compile(
     63             "^" + PkgProps.PKG_REVISION + "=(.*)$"); //$NON-NLS-1$
     64 
     65     /**
     66      * Checks the plugin and the SDK have compatible versions.
     67      * @param osSdkPath The path to the SDK
     68      * @return true if compatible.
     69      */
     70     public static boolean checkVersion(String osSdkPath, CheckSdkErrorHandler errorHandler) {
     71         AdtPlugin plugin = AdtPlugin.getDefault();
     72         String osLibs = osSdkPath + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER;
     73 
     74         // get the plugin property file, and grab the minimum plugin version required
     75         // to work with the sdk
     76         int minMajorVersion = -1;
     77         int minMinorVersion = -1;
     78         int minMicroVersion = -1;
     79         BufferedReader reader = null;
     80         try {
     81             reader = new BufferedReader(new FileReader(osLibs + SdkConstants.FN_PLUGIN_PROP));
     82             String line;
     83             while ((line = reader.readLine()) != null) {
     84                 Matcher m = sPluginVersionPattern.matcher(line);
     85                 if (m.matches()) {
     86                     minMajorVersion = Integer.parseInt(m.group(1));
     87                     minMinorVersion = Integer.parseInt(m.group(2));
     88                     minMicroVersion = Integer.parseInt(m.group(3));
     89                     break;
     90                 }
     91             }
     92         } catch (FileNotFoundException e) {
     93             // the build id will be null, and this is handled by the builders.
     94         } catch (IOException e) {
     95             // the build id will be null, and this is handled by the builders.
     96         } finally {
     97             if (reader != null) {
     98                 try {
     99                     reader.close();
    100                 } catch (IOException e) {
    101                 } finally {
    102                     reader = null;
    103                 }
    104             }
    105         }
    106 
    107         // Failed to get the min plugin version number?
    108         if (minMajorVersion == -1 || minMinorVersion == -1 || minMicroVersion ==-1) {
    109             return errorHandler.handleWarning(
    110                     Solution.OPEN_SDK_MANAGER,
    111                     Messages.VersionCheck_Plugin_Version_Failed);
    112         }
    113 
    114         // Are the build tools installed? We can't query Sdk#getLatestBuildTool yet, since
    115         // SDK initialization typically hasn't completed yet and Sdk.getCurrent() is null.
    116         File buildToolsFolder = new File(osSdkPath, SdkConstants.FD_BUILD_TOOLS);
    117         if (!buildToolsFolder.isDirectory()) {
    118             return errorHandler.handleWarning(
    119                     Solution.OPEN_SDK_MANAGER,
    120                     Messages.VersionCheck_Build_Tool_Missing);
    121         }
    122 
    123         // test the plugin number
    124         String versionString = (String) plugin.getBundle().getHeaders().get(
    125                 Constants.BUNDLE_VERSION);
    126         Version version = new Version(versionString);
    127 
    128         boolean valid = true;
    129         if (version.getMajor() < minMajorVersion) {
    130             valid = false;
    131         } else if (version.getMajor() == minMajorVersion) {
    132             if (version.getMinor() < minMinorVersion) {
    133                 valid = false;
    134             } else if (version.getMinor() == minMinorVersion) {
    135                 if (version.getMicro() < minMicroVersion) {
    136                     valid = false;
    137                 }
    138             }
    139         }
    140 
    141         if (valid == false) {
    142             return errorHandler.handleError(
    143                     Solution.OPEN_P2_UPDATE,
    144                     String.format(Messages.VersionCheck_Plugin_Too_Old,
    145                             minMajorVersion, minMinorVersion, minMicroVersion, versionString));
    146         }
    147 
    148         // now check whether the tools are new enough.
    149         String osTools = osSdkPath + SdkConstants.OS_SDK_TOOLS_FOLDER;
    150         FullRevision toolsRevision = new FullRevision(Integer.MAX_VALUE);
    151         try {
    152             reader = new BufferedReader(new FileReader(osTools + SdkConstants.FN_SOURCE_PROP));
    153             String line;
    154             while ((line = reader.readLine()) != null) {
    155                 Matcher m = sSourcePropPattern.matcher(line);
    156                 if (m.matches()) {
    157                     try {
    158                         toolsRevision = FullRevision.parseRevision(m.group(1));
    159                     } catch (NumberFormatException ignore) {}
    160                     break;
    161                 }
    162             }
    163         } catch (FileNotFoundException e) {
    164             // the build id will be null, and this is handled by the builders.
    165         } catch (IOException e) {
    166             // the build id will be null, and this is handled by the builders.
    167         } finally {
    168             if (reader != null) {
    169                 try {
    170                     reader.close();
    171                 } catch (IOException e) {
    172                 } finally {
    173                     reader = null;
    174                 }
    175             }
    176         }
    177 
    178         if (toolsRevision.compareTo(MIN_TOOLS_REV, PreviewComparison.IGNORE) < 0) {
    179             // this is a warning only as we need to parse the SDK to allow updating
    180             // of the tools!
    181             return errorHandler.handleWarning(
    182                     Solution.OPEN_SDK_MANAGER,
    183                     String.format(Messages.VersionCheck_Tools_Too_Old,
    184                             MIN_TOOLS_REV, toolsRevision));
    185         }
    186 
    187         return true; // no error!
    188     }
    189 }
    190