Home | History | Annotate | Download | only in idegen
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
      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.idegen;
     18 
     19 import com.google.common.base.Preconditions;
     20 import com.google.common.collect.ImmutableList;
     21 import com.google.common.collect.Sets;
     22 
     23 import java.io.File;
     24 import java.io.FileNotFoundException;
     25 import java.io.FilenameFilter;
     26 import java.net.URISyntaxException;
     27 import java.util.HashSet;
     28 import java.util.logging.Level;
     29 import java.util.logging.Logger;
     30 import java.util.regex.Matcher;
     31 import java.util.regex.Pattern;
     32 
     33 /**
     34  * Find directories utility.
     35  */
     36 public class DirectorySearch {
     37 
     38     private static final Logger logger = Logger.getLogger(DirectorySearch.class.getName());
     39 
     40     private static final HashSet<String> SOURCE_DIRS = Sets.newHashSet();
     41     static {
     42         SOURCE_DIRS.add("src");
     43         SOURCE_DIRS.add("java");
     44     }
     45 
     46     private static final Pattern EXCLUDE_PATTERN = Pattern.compile("values-..(-.*)*");
     47 
     48     private static File repoRoot = null;
     49     public static final String REL_TEMPLATE_DIR = "templates";
     50     public static final String REL_TEMPLATE_PATH_FROM_ROOT = "development/tools/idegen/"
     51             + REL_TEMPLATE_DIR;
     52 
     53     /**
     54      * Find the repo root.  This is the root branch directory of a full repo checkout.
     55      *
     56      * @param file any file inside the root.
     57      * @return the root directory.
     58      */
     59     public static File findRepoRoot(File file) {
     60         Preconditions.checkNotNull(file);
     61         if (repoRoot != null) {
     62             return repoRoot;
     63         }
     64 
     65         if (file.isDirectory()) {
     66             File[] files = file.listFiles(new FilenameFilter() {
     67                 @Override
     68                 public boolean accept(File dir, String name) {
     69                    if (".repo".equals(name)) {
     70                        return true;
     71                    }
     72                    return false;
     73                 }
     74             });
     75             if (files.length > 0) {
     76                 repoRoot = file;
     77                 return file;
     78             }
     79         }
     80         File parent = file.getParentFile();
     81         if (parent == null) {
     82             return null;
     83         }
     84         return findRepoRoot(parent);
     85     }
     86 
     87     /**
     88      * Find all source directories from a given root file.
     89      *
     90      * If the root file is a file, the directory of that file will be used as the starting
     91      * location.
     92      *
     93      * @param file The starting location. Can be a file or directory.
     94      * @return List of
     95      */
     96     public static ImmutableList<File> findSourceDirs(File file) {
     97         Preconditions.checkNotNull(file);
     98         if (!file.exists()) {
     99             return ImmutableList.of();
    100         }
    101         if (!file.isDirectory()) {
    102             file = file.getParentFile();
    103         }
    104         ImmutableList.Builder<File> builder = ImmutableList.builder();
    105         File[] children = file.listFiles();
    106         for (File child : children) {
    107             if (child.isDirectory()) {
    108                 if (SOURCE_DIRS.contains(child.getName())) {
    109                     builder.add(child);
    110                 } else {
    111                     ImmutableList<File> dirs = findSourceDirs(child);
    112                     builder.addAll(dirs);
    113                 }
    114             }
    115         }
    116 
    117         return builder.build();
    118     }
    119 
    120     public static ImmutableList<File> findExcludeDirs(File file) {
    121         Preconditions.checkNotNull(file);
    122         if (!file.exists()) {
    123             return ImmutableList.of();
    124         }
    125         if (!file.isDirectory()) {
    126             file = file.getParentFile();
    127         }
    128         ImmutableList.Builder<File> builder = ImmutableList.builder();
    129         // Go into the res folder
    130         File resFile = new File(file, "res");
    131         if (resFile.exists()) {
    132 
    133             File[] children = resFile.listFiles();
    134             for (File child : children) {
    135                 if (child.isDirectory()) {
    136                     Matcher matcher = EXCLUDE_PATTERN.matcher(child.getName());
    137                     if (matcher.matches()) {
    138                         // Exclude internationalization language folders.
    139                         // ex: values-zh
    140                         // But don't exclude values-land.  Assume all language folders are two
    141                         // letters.
    142                         builder.add(child);
    143                     }
    144                 }
    145             }
    146         }
    147 
    148         return builder.build();
    149     }
    150 
    151     private static File templateDirCurrent = null;
    152     private static File templateDirRoot = null;
    153 
    154     public static File findTemplateDir() throws FileNotFoundException {
    155         // Cache optimization.
    156         if (templateDirCurrent != null && templateDirCurrent.exists()) return templateDirCurrent;
    157         if (templateDirRoot != null && templateDirRoot.exists()) return templateDirRoot;
    158 
    159         File currentDir = null;
    160         try {
    161             currentDir = new File(IntellijProject.class.getProtectionDomain().getCodeSource()
    162                     .getLocation().toURI().getPath()).getParentFile();
    163         } catch (URISyntaxException e) {
    164             logger.log(Level.SEVERE, "Could not get jar location.", e);
    165             return null;
    166         }
    167 
    168         // First check relative to current run directory.
    169         templateDirCurrent = new File(currentDir, REL_TEMPLATE_DIR);
    170         if (templateDirCurrent.exists()) {
    171             return templateDirCurrent;
    172         } else {
    173             // Then check relative to root directory.
    174             templateDirRoot = new File(repoRoot, REL_TEMPLATE_PATH_FROM_ROOT);
    175             if (templateDirRoot.exists()) {
    176                 return templateDirRoot;
    177             }
    178         }
    179         throw new FileNotFoundException(
    180                 "Unable to find template dir. Tried the following locations:\n" +
    181                 templateDirCurrent.getAbsolutePath() + "\n" +
    182                 templateDirRoot.getAbsolutePath());
    183     }
    184 }
    185