added a builder to parse files with eclipse's build mechanisms
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / resourcesview / PHPProject.java
1 package net.sourceforge.phpeclipse.resourcesview;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.InputStream;
5 import java.util.ArrayList;
6 import java.util.Iterator;
7 import java.util.List;
8
9 import javax.xml.parsers.SAXParserFactory;
10
11 import net.sourceforge.phpeclipse.LoadPathEntry;
12 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
13
14 import org.eclipse.core.resources.ICommand;
15 import org.eclipse.core.resources.IFile;
16 import org.eclipse.core.resources.IProject;
17 import org.eclipse.core.resources.IProjectDescription;
18 import org.eclipse.core.resources.IProjectNature;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IPath;
22 import org.eclipse.core.runtime.Path;
23 import org.xml.sax.Attributes;
24 import org.xml.sax.ContentHandler;
25 import org.xml.sax.InputSource;
26 import org.xml.sax.Locator;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.XMLReader;
29
30 public class PHPProject implements IProjectNature, PHPElement {
31   protected IProject fProject;
32   protected List loadPathEntries;
33   protected boolean scratched;
34
35   public PHPProject() {
36   }
37
38   public void configure() throws CoreException {
39     //  get project description and then the associated build commands 
40     IProjectDescription desc = fProject.getDescription();
41     ICommand[] commands = desc.getBuildSpec();
42
43     // determine if builder already associated
44     boolean found = false;
45     for (int i = 0; i < commands.length; ++i) {
46       if (commands[i].getBuilderName().equals(PHPeclipsePlugin.BUILDER_PARSER_ID)) {
47         found = true;
48         break;
49       }
50     }
51
52     // add builder if not already in project
53     if (!found) {
54       ICommand command = desc.newCommand();
55       command.setBuilderName(PHPeclipsePlugin.BUILDER_PARSER_ID);
56       ICommand[] newCommands = new ICommand[commands.length + 1];
57
58       // Add it before other builders. 
59       System.arraycopy(commands, 0, newCommands, 1, commands.length);
60       newCommands[0] = command;
61       desc.setBuildSpec(newCommands);
62       fProject.setDescription(desc, null);
63     }
64   }
65
66   public void deconfigure() throws CoreException {
67   }
68
69   public IProject getProject() {
70     return fProject;
71   }
72
73   protected IProject getProject(String name) {
74     return PHPeclipsePlugin.getWorkspace().getRoot().getProject(name);
75   }
76
77   public void setProject(IProject aProject) {
78     fProject = aProject;
79   }
80
81   public void addLoadPathEntry(IProject anotherPHPProject) {
82     scratched = true;
83
84     LoadPathEntry newEntry = new LoadPathEntry(anotherPHPProject);
85     getLoadPathEntries().add(newEntry);
86   }
87
88   public void removeLoadPathEntry(IProject anotherPHPProject) {
89     Iterator entries = getLoadPathEntries().iterator();
90     while (entries.hasNext()) {
91       LoadPathEntry entry = (LoadPathEntry) entries.next();
92       if (entry.getType() == LoadPathEntry.TYPE_PROJECT
93         && entry.getProject().getName().equals(anotherPHPProject.getName())) {
94         getLoadPathEntries().remove(entry);
95         scratched = true;
96         break;
97       }
98     }
99   }
100
101   public List getLoadPathEntries() {
102     if (loadPathEntries == null) {
103       loadLoadPathEntries();
104     }
105
106     return loadPathEntries;
107   }
108
109   public List getReferencedProjects() {
110     List referencedProjects = new ArrayList();
111
112     Iterator iterator = getLoadPathEntries().iterator();
113     while (iterator.hasNext()) {
114       LoadPathEntry pathEntry = (LoadPathEntry) iterator.next();
115       if (pathEntry.getType() == LoadPathEntry.TYPE_PROJECT)
116         referencedProjects.add(pathEntry.getProject());
117     }
118
119     return referencedProjects;
120   }
121
122   protected void loadLoadPathEntries() {
123     loadPathEntries = new ArrayList();
124
125     IFile loadPathsFile = getLoadPathEntriesFile();
126
127     XMLReader reader = null;
128     try {
129       reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
130       reader.setContentHandler(getLoadPathEntriesContentHandler());
131       reader.parse(new InputSource(loadPathsFile.getContents()));
132     } catch (Exception e) {
133       //the file is nonextant or unreadable
134     }
135   }
136
137   protected ContentHandler getLoadPathEntriesContentHandler() {
138     return new ContentHandler() {
139       public void characters(char[] arg0, int arg1, int arg2)
140         throws SAXException {
141       }
142
143       public void endDocument() throws SAXException {
144       }
145
146       public void endElement(String arg0, String arg1, String arg2)
147         throws SAXException {
148       }
149
150       public void endPrefixMapping(String arg0) throws SAXException {
151       }
152
153       public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
154         throws SAXException {
155       }
156
157       public void processingInstruction(String arg0, String arg1)
158         throws SAXException {
159       }
160
161       public void setDocumentLocator(Locator arg0) {
162       }
163
164       public void skippedEntity(String arg0) throws SAXException {
165       }
166
167       public void startDocument() throws SAXException {
168       }
169
170       public void startElement(
171         String namespaceURI,
172         String localName,
173         String qName,
174         Attributes atts)
175         throws SAXException {
176         if ("pathentry".equals(qName))
177           if ("project".equals(atts.getValue("type"))) {
178             IPath referencedProjectPath = new Path(atts.getValue("path"));
179             IProject referencedProject =
180               getProject(referencedProjectPath.lastSegment());
181             loadPathEntries.add(new LoadPathEntry(referencedProject));
182           }
183       }
184
185       public void startPrefixMapping(String arg0, String arg1)
186         throws SAXException {
187       }
188     };
189   }
190
191   protected IFile getLoadPathEntriesFile() {
192     return fProject.getFile(".loadpath");
193   }
194
195   public void save() throws CoreException {
196     if (scratched) {
197       InputStream xmlPath =
198         new ByteArrayInputStream(getLoadPathXML().getBytes());
199       IFile loadPathsFile = getLoadPathEntriesFile();
200       if (!loadPathsFile.exists())
201         loadPathsFile.create(xmlPath, true, null);
202       else
203         loadPathsFile.setContents(xmlPath, true, false, null);
204
205       scratched = false;
206     }
207   }
208
209   protected String getLoadPathXML() {
210     StringBuffer buffer = new StringBuffer();
211     buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><loadpath>");
212
213     Iterator pathEntriesIterator = loadPathEntries.iterator();
214
215     while (pathEntriesIterator.hasNext()) {
216       LoadPathEntry entry = (LoadPathEntry) pathEntriesIterator.next();
217       buffer.append(entry.toXML());
218     }
219
220     buffer.append("</loadpath>");
221     return buffer.toString();
222   }
223
224   public IResource getUnderlyingResource() {
225     return fProject;
226   }
227
228 }