001    package org.extendj.ast;
002    
003    import java.util.HashSet;
004    import java.io.File;
005    import java.util.Set;
006    import java.util.Collections;
007    import java.util.Collection;
008    import java.util.ArrayList;
009    import beaver.*;
010    import java.util.*;
011    import java.io.ByteArrayOutputStream;
012    import java.io.PrintStream;
013    import java.lang.reflect.InvocationTargetException;
014    import java.lang.reflect.Method;
015    import org.jastadd.util.*;
016    import java.util.zip.*;
017    import java.io.*;
018    import org.jastadd.util.PrettyPrintable;
019    import org.jastadd.util.PrettyPrinter;
020    import java.io.FileNotFoundException;
021    import java.io.BufferedInputStream;
022    import java.io.DataInputStream;
023    /**
024     * @ast class
025     * @aspect PathPart
026     * @declaredat /home/jesper/git/extendj/java4/frontend/PathPart.jadd:391
027     */
028    public abstract class FolderPath extends PathPart {
029      
030        /**
031         * The root folder of this path part.
032         */
033        private final File folder;
034    
035      
036        private final String folderPath;
037    
038      
039    
040        protected FolderPath(String folderPath, boolean isSource) {
041          super(isSource);
042          this.folder = new File(folderPath);
043          this.folderPath = folderPath;
044        }
045    
046      
047    
048        protected FolderPath(File folder, boolean isSource) {
049          super(isSource);
050          this.folder = folder;
051          this.folderPath = folder.getPath();
052        }
053    
054      
055    
056        @Override
057        public String getPath() {
058          return folderPath;
059        }
060    
061      
062    
063        /**
064         * Check if the package exists as a subdirectory.
065         *
066         * <p>We need to use getCanonicalFile in order to get the case-sensitive
067         * package name on case-insensitive file systems or we might incorrectly
068         * report a package name conflict.
069         *
070         * <p>NB: This does not work well with symlinks!
071         *
072         * @param name The qualified name of the package
073         * @return {@code true} if the subdirectory matching the package exists
074         * and contains at least one source or class file.
075         */
076        @Override
077        public boolean hasPackage(String name) {
078          boolean packageIsEmpty = true;
079          int index = name.lastIndexOf('.');
080          String basePackageName = name.substring(index == -1 ? 0 : index+1);
081          String subdir = name.replace('.', File.separatorChar);
082          File pkgFolder = new File(folder, subdir);
083          Collection<String> fileSet = Collections.emptyList();
084          try {
085            // Make sure that there exists a directory with the same name
086            // (case-sensitive) as the requested package
087            File canonical = pkgFolder.getCanonicalFile();
088            if (canonical.isDirectory() && (name.isEmpty() ||
089                  canonical.getName().equals(basePackageName))) {
090              File[] files = canonical.listFiles();
091              for (File file: files) {
092                if (file.isFile() && file.getName().endsWith(fileSuffix)) {
093                  // found one source file in the package
094                  packageIsEmpty = false;
095                  break;
096                }
097              }
098            }
099          } catch (Exception e) {
100            // if an exception is thrown then packageIsEmpty will be false
101            // which indicates that the package does not exist
102            // The likely cause of the exception would be getCanonicalFile
103          }
104          return !packageIsEmpty;
105        }
106    
107      
108    
109        @Override
110        public ClassSource findSource(String name) {
111          String filePath = name.replace('.', File.separatorChar) + fileSuffix;
112          File classFile = new File(folder, filePath);
113          if (classFile.isFile() && classFile.canRead()) {
114            String pathName = classFile.getPath();
115            if (isSource) {
116              return new FileClassSource(this, pathName);
117            } else {
118              return new FileBytecodeClassSource(this, pathName);
119            }
120          }
121          return ClassSource.NONE;
122        }
123    
124      
125    
126        @Override
127        public String toString() {
128          return folder.getPath();
129        }
130    
131    
132    }