Home | History | Annotate | Download | only in discovery
      1 /*
      2  * Copyright (C) 2011 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.ndk.internal.discovery;
     18 
     19 import com.android.ide.eclipse.adt.ndk.internal.Activator;
     20 
     21 import org.eclipse.cdt.core.CCorePlugin;
     22 import org.eclipse.cdt.core.model.CoreModel;
     23 import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
     24 import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable;
     25 import org.eclipse.core.resources.IFile;
     26 import org.eclipse.core.resources.IProject;
     27 import org.eclipse.core.runtime.CoreException;
     28 import org.eclipse.core.runtime.IPath;
     29 import org.eclipse.core.runtime.IProgressMonitor;
     30 import org.eclipse.core.runtime.Path;
     31 
     32 import java.io.BufferedReader;
     33 import java.io.File;
     34 import java.io.FileReader;
     35 import java.io.IOException;
     36 import java.io.PrintStream;
     37 import java.util.ArrayList;
     38 import java.util.HashMap;
     39 import java.util.List;
     40 import java.util.Map;
     41 import java.util.Map.Entry;
     42 
     43 public class NdkDiscoveredPathInfo implements IDiscoveredPathInfo {
     44 
     45     private final IProject mProject;
     46     private long mLastUpdate = IFile.NULL_STAMP;
     47     private IPath[] mIncludePaths;
     48     private Map<String, String> mSymbols;
     49     private boolean mNeedReindexing = false;
     50     private static final IPath ANDROID_MK = new Path("jni/Android.mk");
     51 
     52     // Keys for preferences
     53     public static final String LAST_UPDATE = "lastUpdate"; //$NON-NLS-1$
     54 
     55     public NdkDiscoveredPathInfo(IProject project) {
     56         this.mProject = project;
     57         load();
     58     }
     59 
     60     public IProject getProject() {
     61         return mProject;
     62     }
     63 
     64     public IPath[] getIncludePaths() {
     65         if (mNeedReindexing) {
     66             // Call for a reindex
     67             // TODO this is probably a bug. a new include path should trigger
     68             // reindexing anyway, no?
     69             // BTW, can't do this in the update since the indexer runs before
     70             // this gets called
     71             CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(mProject));
     72             mNeedReindexing = false;
     73         }
     74         return mIncludePaths;
     75     }
     76 
     77     void setIncludePaths(List<String> pathStrings) {
     78         mIncludePaths = new IPath[pathStrings.size()];
     79         int i = 0;
     80         for (String path : pathStrings)
     81             mIncludePaths[i++] = new Path(path);
     82         mNeedReindexing = true;
     83     }
     84 
     85     public Map<String, String> getSymbols() {
     86         if (mSymbols == null)
     87             mSymbols = new HashMap<String, String>();
     88         return mSymbols;
     89     }
     90 
     91     void setSymbols(Map<String, String> symbols) {
     92         this.mSymbols = symbols;
     93     }
     94 
     95     public IDiscoveredScannerInfoSerializable getSerializable() {
     96         return null;
     97     }
     98 
     99     public void update(IProgressMonitor monitor) throws CoreException {
    100         if (!needUpdating())
    101             return;
    102 
    103         new NdkDiscoveryUpdater(this).runUpdate(monitor);
    104 
    105         if (mIncludePaths != null && mSymbols != null) {
    106             recordUpdate();
    107             save();
    108         }
    109     }
    110 
    111     private boolean needUpdating() {
    112         if (mLastUpdate == IFile.NULL_STAMP)
    113             return true;
    114         return mProject.getFile(ANDROID_MK).getLocalTimeStamp() > mLastUpdate; //$NON-NLS-1$
    115     }
    116 
    117     private void recordUpdate() {
    118         mLastUpdate = mProject.getFile(ANDROID_MK).getLocalTimeStamp(); //$NON-NLS-1$
    119     }
    120 
    121     public void delete() {
    122         mLastUpdate = IFile.NULL_STAMP;
    123     }
    124 
    125     private File getInfoFile() {
    126         File stateLoc = Activator.getDefault().getStateLocation().toFile();
    127         return new File(stateLoc, mProject.getName() + ".pathInfo"); //$NON-NLS-1$
    128     }
    129 
    130     private void save() {
    131         try {
    132             File infoFile = getInfoFile();
    133             infoFile.getParentFile().mkdirs();
    134             PrintStream out = new PrintStream(infoFile);
    135 
    136             // timestamp
    137             out.print("t,"); //$NON-NLS-1$
    138             out.print(mLastUpdate);
    139             out.println();
    140 
    141             for (IPath include : mIncludePaths) {
    142                 out.print("i,"); //$NON-NLS-1$
    143                 out.print(include.toPortableString());
    144                 out.println();
    145             }
    146 
    147             for (Entry<String, String> symbol : mSymbols.entrySet()) {
    148                 out.print("d,"); //$NON-NLS-1$
    149                 out.print(symbol.getKey());
    150                 out.print(","); //$NON-NLS-1$
    151                 out.print(symbol.getValue());
    152                 out.println();
    153             }
    154 
    155             out.close();
    156         } catch (IOException e) {
    157             Activator.log(e);
    158         }
    159 
    160     }
    161 
    162     private void load() {
    163         try {
    164             File infoFile = getInfoFile();
    165             if (!infoFile.exists())
    166                 return;
    167 
    168             long timestamp = IFile.NULL_STAMP;
    169             List<IPath> includes = new ArrayList<IPath>();
    170             Map<String, String> defines = new HashMap<String, String>();
    171 
    172             BufferedReader reader = new BufferedReader(new FileReader(infoFile));
    173             for (String line = reader.readLine(); line != null; line = reader.readLine()) {
    174                 switch (line.charAt(0)) {
    175                     case 't':
    176                         timestamp = Long.valueOf(line.substring(2));
    177                         break;
    178                     case 'i':
    179                         includes.add(Path.fromPortableString(line.substring(2)));
    180                         break;
    181                     case 'd':
    182                         int n = line.indexOf(',', 2);
    183                         if (n == -1)
    184                             defines.put(line.substring(2), ""); //$NON-NLS-1$
    185                         else
    186                             defines.put(line.substring(2, n), line.substring(n + 1));
    187                         break;
    188                 }
    189             }
    190             reader.close();
    191 
    192             mLastUpdate = timestamp;
    193             mIncludePaths = includes.toArray(new IPath[includes.size()]);
    194             mSymbols = defines;
    195         } catch (IOException e) {
    196             Activator.log(e);
    197         }
    198     }
    199 }
    200