/* * Copyright 2000-2010 JetBrains s.r.o. * * 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://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.jetbrains.android.sdk; import com.android.SdkConstants; import com.android.sdklib.AndroidVersion; import com.android.sdklib.IAndroidTarget; import com.intellij.openapi.module.Module; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.PathUtil; import com.intellij.util.containers.HashSet; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; import java.util.Set; import static org.jetbrains.android.sdk.AndroidSdkUtils.isAndroidSdk; /** * Created by IntelliJ IDEA. * User: Eugene.Kudelevsky * Date: Aug 15, 2009 * Time: 6:54:34 PM * To change this template use File | Settings | File Templates. */ public class AndroidPlatform { private final AndroidSdkData mySdkData; private final IAndroidTarget myTarget; public AndroidPlatform(@NotNull AndroidSdkData sdkData, @NotNull IAndroidTarget target) { mySdkData = sdkData; myTarget = target; } @Nullable public static AndroidPlatform getInstance(@NotNull Module module) { final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); return sdk != null ? getInstance(sdk) : null; } @Nullable public static AndroidPlatform getInstance(@NotNull Sdk sdk) { if (!(sdk.getSdkType() instanceof AndroidSdkType)) { return null; } final AndroidSdkAdditionalData sdkAdditionalData = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); if (sdkAdditionalData == null) { return null; } return sdkAdditionalData.getAndroidPlatform(); } @NotNull public AndroidSdkData getSdkData() { return mySdkData; } @NotNull public IAndroidTarget getTarget() { return myTarget; } @Nullable public static AndroidPlatform parse(@NotNull Sdk sdk) { if (!isAndroidSdk(sdk)) { return null; } String sdkPath = sdk.getHomePath(); if (sdkPath != null) { AndroidSdkData sdkData = AndroidSdkData.getSdkData(sdkPath); if (sdkData != null) { AndroidSdkAdditionalData data = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); IAndroidTarget target = data != null ? data.getBuildTarget(sdkData) : null; if (target != null) { return new AndroidPlatform(sdkData, target); } } } return null; } // deprecated, use only for converting @Nullable @Deprecated public static AndroidPlatform parse(@NotNull Library library, @Nullable Library.ModifiableModel model, @Nullable Map<String, AndroidSdkData> parsedSdks) { VirtualFile[] files = model != null ? model.getFiles(OrderRootType.CLASSES) : library.getFiles(OrderRootType.CLASSES); Set<String> jarPaths = new HashSet<String>(); VirtualFile frameworkLibrary = null; for (VirtualFile file : files) { VirtualFile vFile = JarFileSystem.getInstance().getVirtualFileForJar(file); if (vFile != null) { if (vFile.getName().equals(SdkConstants.FN_FRAMEWORK_LIBRARY)) { frameworkLibrary = vFile; } jarPaths.add(vFile.getPath()); } } if (frameworkLibrary != null) { VirtualFile sdkDir = frameworkLibrary.getParent(); if (sdkDir != null) { VirtualFile platformsDir = sdkDir.getParent(); if (platformsDir != null && platformsDir.getName().equals(SdkConstants.FD_PLATFORMS)) { sdkDir = platformsDir.getParent(); if (sdkDir == null) return null; } String sdkPath = sdkDir.getPath(); AndroidSdkData sdkData = parsedSdks != null ? parsedSdks.get(sdkPath) : null; if (sdkData == null) { sdkData = AndroidSdkData.getSdkData(sdkPath); if (sdkData == null) return null; if (parsedSdks != null) { parsedSdks.put(sdkPath, sdkData); } } IAndroidTarget resultTarget = null; for (IAndroidTarget target : sdkData.getTargets()) { String targetsFrameworkLibPath = PathUtil.getCanonicalPath(target.getPath(IAndroidTarget.ANDROID_JAR)); if (frameworkLibrary.getPath().equals(targetsFrameworkLibPath)) { if (target.isPlatform()) { if (resultTarget == null) resultTarget = target; } else { boolean ok = true; IAndroidTarget.IOptionalLibrary[] libraries = target.getOptionalLibraries(); if (libraries == null) { // we cannot identify add-on target without optional libraries by classpath ok = false; } else { for (IAndroidTarget.IOptionalLibrary optionalLibrary : libraries) { if (!jarPaths.contains(PathUtil.getCanonicalPath(optionalLibrary.getJarPath()))) { ok = false; } } } if (ok) resultTarget = target; } } } if (resultTarget != null) { return new AndroidPlatform(sdkData, resultTarget); } } } return null; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AndroidPlatform platform = (AndroidPlatform)o; if (!mySdkData.equals(platform.mySdkData)) return false; if (!myTarget.equals(platform.myTarget)) return false; return true; } @Override public int hashCode() { int result = mySdkData.hashCode(); result = 31 * result + myTarget.hashCode(); return result; } public boolean needToAddAnnotationsJarToClasspath() { // todo: check if we really don't need to add this return getApiLevel() <= 15; } public int getApiLevel() { return myTarget.getVersion().getApiLevel(); } public AndroidVersion getApiVersion() { return myTarget.getVersion(); } /** Looks up the platform for a given module */ @Nullable public static AndroidPlatform getPlatform(Module module) { if (AndroidFacet.getInstance(module) != null) { Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); if (sdk != null && sdk.getSdkType() instanceof AndroidSdkType) { final AndroidSdkAdditionalData additionalData = (AndroidSdkAdditionalData)sdk.getSdkAdditionalData(); if (additionalData != null) { return additionalData.getAndroidPlatform(); } } } return null; } }