Bugs item #1236682
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / actions / IncludesScanner.java
1 package net.sourceforge.phpeclipse.actions;
2
3 import java.io.BufferedInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.ArrayList;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
12 import net.sourceforge.phpdt.core.compiler.InvalidInputException;
13 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
14 import net.sourceforge.phpdt.internal.compiler.parser.SyntaxError;
15 import net.sourceforge.phpdt.internal.compiler.util.Util;
16
17 import org.eclipse.core.resources.IContainer;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.Path;
22 import org.eclipse.ui.IFileEditorInput;
23
24
25 public class IncludesScanner implements ITerminalSymbols {
26 //  private final PHPOpenAllIncludesEditorAction fOpenAllIncludesAction;
27   private IProject fProject;
28   private IFileEditorInput fEditorInput;
29   private HashSet fSet;
30   public IncludesScanner(IProject project, IFileEditorInput editorInput) {
31     fProject = project;
32 //    fOpenAllIncludesAction = action;
33     fEditorInput = editorInput;
34     fSet = new HashSet();
35   }
36   /**
37    * Add the information for a given IFile resource
38    *  
39    */
40   public void addFile(IFile fileToParse) {
41
42     try {
43       if (fileToParse.exists()) {
44         addInputStream(new BufferedInputStream(fileToParse.getContents()), fileToParse.getProjectRelativePath().toString());
45       }
46     } catch (CoreException e1) {
47       e1.printStackTrace();
48     }
49   }
50
51   private void addInputStream(InputStream stream, String filePath) throws CoreException {
52     try {
53       if (fSet.add(filePath)) { // new entry in set
54         parseIdentifiers(Util.getInputStreamAsCharArray(stream, -1, null));
55       }
56     } catch (IOException e) {
57       e.printStackTrace();
58     } finally {
59       try {
60         if (stream != null) {
61           stream.close();
62         }
63       } catch (IOException e) {
64       }
65     }
66   }
67
68   /**
69    * Get the next token from input
70    */
71   private int getNextToken(Scanner scanner) {
72     int token;
73     try {
74       token = scanner.getNextToken();
75       if (Scanner.DEBUG) {
76         int currentEndPosition = scanner.getCurrentTokenEndPosition();
77         int currentStartPosition = scanner.getCurrentTokenStartPosition();
78         System.out.print(currentStartPosition + "," + currentEndPosition + ": ");
79         System.out.println(scanner.toStringAction(token));
80       }
81       return token;
82     } catch (InvalidInputException e) {
83     }
84     return TokenNameERROR;
85   }
86
87   private void parseIdentifiers(char[] charArray) {
88     char[] ident;
89     IFile file;
90     String identifier;
91     int counter = 0;
92
93     Scanner scanner = new Scanner(false, false, false, false, true, null, null, true /*taskCaseSensitive*/);
94     scanner.setSource(charArray);
95     scanner.setPHPMode(false);
96     int token = getNextToken(scanner);
97     try {
98       while (token != TokenNameEOF) { // && fToken != TokenNameERROR) {
99         if (token == TokenNameinclude || token == TokenNameinclude_once || token == TokenNamerequire
100             || token == TokenNamerequire_once) {
101           while (token != TokenNameEOF && token != TokenNameERROR && token != TokenNameSEMICOLON && token != TokenNameRPAREN
102               && token != TokenNameLBRACE && token != TokenNameRBRACE) {
103             token = getNextToken(scanner);
104             if (token == TokenNameStringDoubleQuote || token == TokenNameStringSingleQuote) {
105               char[] includeName = scanner.getCurrentStringLiteralSource();
106               try {
107                 file = getIncludeFile(new String(includeName));
108                 addFile(file);
109               } catch (Exception e) {
110                 // ignore
111               }
112               break;
113             }
114           }
115         }
116         token = getNextToken(scanner);
117       }
118     } catch (SyntaxError e) {
119      // e.printStackTrace();
120     }
121   }
122   
123   private IContainer getWorkingLocation(IFileEditorInput editorInput) {
124     if (editorInput == null || editorInput.getFile() == null) {
125       return null;
126     }
127     return editorInput.getFile().getParent();
128   }
129   public IFile getIncludeFile(String relativeFilename) {
130     IContainer container = getWorkingLocation(fEditorInput);
131     String fullPath = fProject.getLocation().toString();
132     IFile file = null;
133     if (relativeFilename.startsWith("../")) {
134       Path path = new Path(relativeFilename);
135       file = container.getFile(path);
136       return file;
137     }
138     int index = relativeFilename.lastIndexOf('/');
139
140     if (index >= 0) {
141       Path path = new Path(relativeFilename);
142       file = fProject.getFile(path);
143       if (file.exists()) {
144         return file;
145       }
146     }
147     Path path = new Path(relativeFilename);
148     file = container.getFile(path);
149
150     return file;
151   }
152   /**
153    * Returns a list of includes
154    * @return the determined list of includes 
155    */
156   public List getList() {
157     ArrayList list = new ArrayList();
158     list.addAll(fSet);
159     return list;
160   }
161
162   /**
163    * @return Returns the set.
164    */
165   public Set getSet() {
166     return fSet;
167   }
168 }