Source Code Cross Referenced for ProjectFileParser.java in  » IDE » DrJava » edu » rice » cs » drjava » project » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.drjava.project 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.drjava.project;
038:
039:        import java.io.File;
040:        import java.io.IOException;
041:        import java.io.FileNotFoundException;
042:        import java.util.List;
043:        import java.util.ArrayList;
044:        import java.util.Date;
045:        import java.text.SimpleDateFormat;
046:
047:        import edu.rice.cs.drjava.config.FileOption;
048:        import edu.rice.cs.plt.tuple.Pair;
049:        import edu.rice.cs.util.sexp.*;
050:        import edu.rice.cs.drjava.model.DocumentRegion;
051:        import edu.rice.cs.drjava.model.SimpleDocumentRegion;
052:        import edu.rice.cs.drjava.model.OpenDefinitionsDocument;
053:        import edu.rice.cs.drjava.model.debug.DebugWatchData;
054:        import edu.rice.cs.drjava.model.debug.DebugBreakpointData;
055:        import edu.rice.cs.drjava.model.debug.DebugException;
056:
057:        /** This parser uses the s-expression parser defined in the util pacakge.  The SExp tree given by the parser is 
058:         *  interpreted into a ProjectFileIR that is given to the user.  This class must also deal with different
059:         *  versions of the project file.
060:         * 
061:         *  <p> If at some point new information is to be stored in the project file, the following places in the code that need to
062:         *  changed: <menu> <li> If the new information pertains to a document, the DocFile class should be augmented to
063:         *  store the new info.  <li> The interface for the DocumentInfoGetter should be expanded to allow for the new
064:         *  data to be retrieved.  <li> Add a new clause to the else-if ladder in the FilePropertyVisitor.  <li> 
065:         *  Add the new information to the DocFile form the DocumentInfoGetter in the ProjectFileBuilder's 
066:         *  addSourceDocument method.</p>
067:         * 
068:         *  <p> If the change is at the top level, you must modify the evaluateExpression method in this parser and add the 
069:         *  corresponding methods to the ProjectFileIR, ProjectFileIRImpl, and ProjectFileBuilder</p>
070:         */
071:        public class ProjectFileParser {
072:            /** Singleton instance of ProjectFileParser */
073:            public static final ProjectFileParser ONLY = new ProjectFileParser();
074:
075:            private File _projectFile;
076:            private String _parent;
077:            private String _srcFileBase;
078:
079:            BreakpointListVisitor breakpointListVisitor = new BreakpointListVisitor();
080:            BookmarkListVisitor bookmarkListVisitor = new BookmarkListVisitor();
081:
082:            private ProjectFileParser() {
083:            }
084:
085:            /* methods */
086:
087:            /** @param projFile the file to parse
088:             *  @return the project file IR
089:             */
090:            public ProjectFileIR parse(File projFile) throws IOException,
091:                    FileNotFoundException, MalformedProjectFileException {
092:
093:                _projectFile = projFile;
094:                _parent = projFile.getParent();
095:                _srcFileBase = _parent; // oldest legacy file format may omit proj-root or proj-root-and-base node
096:                //    System.err.println("Parsing project file " + projFile + " with parent " + _parent);
097:
098:                List<SEList> forest = null;
099:                try {
100:                    forest = SExpParser.parse(projFile);
101:                } catch (SExpParseException e) {
102:                    throw new MalformedProjectFileException("Parse Error: "
103:                            + e.getMessage());
104:                }
105:
106:                ProjectFileIR pfir = new ProjectProfile(projFile);
107:
108:                try {
109:                    for (SEList exp : forest)
110:                        evaluateExpression(exp, pfir, new DocFileListVisitor(
111:                                _parent));
112:                } catch (PrivateProjectException e) {
113:                    throw new MalformedProjectFileException("Parse Error: "
114:                            + e.getMessage());
115:                }
116:
117:                //    System.err.println("Parsed buildDir is " + pfir.getBuildDirectory());
118:
119:                return pfir;
120:            }
121:
122:            /** Given a top-level s-expression, this method checks the name of the node and configures the given pfir 
123:             *  appropriately.  If the expression is empty, it is ignored.
124:             *  @param e the top-level s-expression to check
125:             *  @param pfir the ProjectFileIR to update
126:             */
127:            private void evaluateExpression(SEList e, ProjectFileIR pfir,
128:                    DocFileListVisitor flv) throws IOException {
129:                if (e == Empty.ONLY)
130:                    return;
131:                Cons exp = (Cons) e; // If it's not empty, it's a cons
132:
133:                String name = exp.accept(NameVisitor.ONLY);
134:                if ((name.compareToIgnoreCase("source") == 0)
135:                        || (name.compareToIgnoreCase("source-files") == 0)) {
136:                    List<DocFile> dfList = exp.getRest().accept(
137:                            new DocFileListVisitor(_srcFileBase));
138:                    pfir.setSourceFiles(dfList);
139:                } else if (name.compareToIgnoreCase("proj-root") == 0) { // legacy node form; all paths relative to project file
140:                    List<DocFile> fList = exp.getRest().accept(flv);
141:                    if (fList.size() > 1)
142:                        throw new PrivateProjectException(
143:                                "Cannot have multiple source roots");
144:                    else if (fList.size() == 0)
145:                        pfir.setProjectRoot(null); // can this ever happen?
146:                    pfir.setProjectRoot(fList.get(0));
147:                } else if (name.compareToIgnoreCase("proj-root-and-base") == 0) { // source file paths are relative to project root
148:                    List<DocFile> fList = exp.getRest().accept(flv);
149:                    if (fList.size() > 1)
150:                        throw new PrivateProjectException(
151:                                "Cannot have multiple source roots");
152:                    File root = fList.get(0);
153:                    if (!root.exists())
154:                        throw new IOException("Project root " + root
155:                                + " no longer exists");
156:                    pfir.setProjectRoot(root);
157:                    _srcFileBase = root.getCanonicalPath();
158:                } else if (name.compareToIgnoreCase("auxiliary") == 0) {
159:                    List<DocFile> dfList = exp.getRest().accept(flv);
160:                    pfir.setAuxiliaryFiles(dfList);
161:                } else if (name.compareToIgnoreCase("collapsed") == 0) {
162:                    List<String> sList = exp.getRest().accept(
163:                            PathListVisitor.ONLY);
164:                    pfir.setCollapsedPaths(sList);
165:                } else if (name.compareToIgnoreCase("build-dir") == 0) {
166:                    List<DocFile> fList = exp.getRest().accept(flv);
167:                    //      System.err.println("BuildDir fList = " + fList);
168:                    if (fList.size() > 1)
169:                        throw new PrivateProjectException(
170:                                "Cannot have multiple build directories");
171:                    else if (fList.size() == 0)
172:                        pfir.setBuildDirectory(null);
173:                    else
174:                        pfir.setBuildDirectory(fList.get(0));
175:                } else if (name.compareToIgnoreCase("work-dir") == 0) {
176:                    List<DocFile> fList = exp.getRest().accept(flv);
177:                    if (fList.size() > 1)
178:                        throw new PrivateProjectException(
179:                                "Cannot have multiple working directories");
180:                    else if (fList.size() == 0)
181:                        pfir.setWorkingDirectory(null);
182:                    else
183:                        pfir.setWorkingDirectory(fList.get(0));
184:                } else if (name.compareToIgnoreCase("classpaths") == 0) {
185:                    List<DocFile> fList = exp.getRest().accept(flv);
186:                    pfir.setClassPaths(fList);
187:                } else if (name.compareToIgnoreCase("main-class") == 0) {
188:                    List<DocFile> fList = exp.getRest().accept(flv);
189:                    if (fList.size() > 1)
190:                        throw new PrivateProjectException(
191:                                "Cannot have multiple main classes");
192:                    else if (fList.size() == 0)
193:                        pfir.setMainClass(null);
194:                    else
195:                        pfir.setMainClass(fList.get(0));
196:                }
197:                //    else if (name.compareToIgnoreCase("create-jar-file") == 0) {
198:                //      List<File> fList = exp.getRest().accept(fileListVisitor);
199:                //      if (fList.size() > 1) throw new PrivateProjectException("Cannot have more than one \"create jar\" file");
200:                //      else if (fList.size() == 0) pfir.setCreateJarFile(null);
201:                //      else pfir.setCreateJarFile(fList.get(0));
202:                //    }
203:                //    else if (name.compareToIgnoreCase("create-jar-flags") == 0) {
204:                //      Integer i = exp.getRest().accept(NumberVisitor.ONLY);
205:                //      pfir.setCreateJarFlags(i);
206:                //    }
207:                else if (name.compareToIgnoreCase("breakpoints") == 0) {
208:                    List<DebugBreakpointData> bpList = exp.getRest().accept(
209:                            breakpointListVisitor);
210:                    pfir.setBreakpoints(bpList);
211:                } else if (name.compareToIgnoreCase("watches") == 0) {
212:                    List<DebugWatchData> sList = exp.getRest().accept(
213:                            WatchListVisitor.ONLY);
214:                    pfir.setWatches(sList);
215:                } else if (name.compareToIgnoreCase("bookmarks") == 0) {
216:                    List<DocumentRegion> bmList = exp.getRest().accept(
217:                            bookmarkListVisitor);
218:                    pfir.setBookmarks(bmList);
219:                }
220:            }
221:
222:            /** Parses out the labeled node (a non-empty list) into a DocFile. The node must have the "file" label on it.
223:             *  @param s the non-empty list expression
224:             *  @return the DocFile described by this s-expression
225:             */
226:            DocFile parseFile(SExp s, String pathRoot) {
227:                String name = s.accept(NameVisitor.ONLY);
228:                if (name.compareToIgnoreCase("file") != 0)
229:                    throw new PrivateProjectException(
230:                            "Expected a file tag, found: " + name);
231:                if (!(s instanceof  Cons))
232:                    throw new PrivateProjectException(
233:                            "Expected a labeled node, found a label: " + name);
234:                SEList c = ((Cons) s).getRest(); // get parameter list
235:
236:                DocFilePropertyVisitor v = new DocFilePropertyVisitor(pathRoot);
237:                return c.accept(v);
238:            }
239:
240:            private String parseFileName(SExp s) {
241:                if (s instanceof  Cons) {
242:                    SEList l = ((Cons) s).getRest();
243:                    if (l == Empty.ONLY)
244:                        throw new PrivateProjectException(
245:                                "expected filename, but nothing found");
246:                    else {
247:                        String name = l.accept(NameVisitor.ONLY);
248:                        name = edu.rice.cs.util.StringOps.replace(name, "\\",
249:                                "/");
250:                        return name;
251:                    }
252:                } else
253:                    throw new PrivateProjectException(
254:                            "expected name tag, found string");
255:            }
256:
257:            private int parseInt(SExp s) {
258:                if (s instanceof  Cons) {
259:                    SEList l = ((Cons) s).getRest();
260:                    if (l == Empty.ONLY)
261:                        throw new PrivateProjectException(
262:                                "expected integer, but nothing found");
263:                    else {
264:                        int i = l.accept(NumberVisitor.ONLY);
265:                        return i;
266:                    }
267:                } else
268:                    throw new PrivateProjectException(
269:                            "expected name tag, found string");
270:            }
271:
272:            private Pair<Integer, Integer> parseIntPair(SExp s) {
273:                int row;
274:                int col;
275:
276:                /* we're getting in a "(select # #)" */
277:                if (!(s instanceof  Cons)) {
278:                    throw new PrivateProjectException(
279:                            "expected name tag, found string");
280:                }
281:
282:                // get rid of "select"
283:                final List<Integer> intList = new ArrayList<Integer>();
284:                SEList l = ((Cons) s).getRest();
285:                List<Integer> li = l.accept(new SExpVisitor<List<Integer>>() {
286:                    public List<Integer> forEmpty(Empty e) {
287:                        return intList;
288:                    }
289:
290:                    public List<Integer> forCons(Cons c) {
291:                        c.getFirst().accept(this );
292:                        return c.getRest().accept(this );
293:                    }
294:
295:                    public List<Integer> forBoolAtom(BoolAtom b) {
296:                        throw new PrivateProjectException(
297:                                "unexpected boolean found, int expected");
298:                    }
299:
300:                    public List<Integer> forNumberAtom(NumberAtom n) {
301:                        intList.add(new Integer(n.intValue()));
302:                        return intList;
303:                    }
304:
305:                    public List<Integer> forTextAtom(TextAtom t) {
306:                        throw new PrivateProjectException(
307:                                "unexpected string found where number expected: "
308:                                        + t.getText());
309:                    }
310:
311:                });
312:
313:                if (li.size() == 2)
314:                    return new Pair<Integer, Integer>(li.get(0), li.get(1));
315:                else
316:                    throw new PrivateProjectException(
317:                            "expected a list of 2 ints for select, found list of size "
318:                                    + li.size());
319:            }
320:
321:            /** Takes input of form "(str str)" and returns the second string. */
322:            private String parseStringNode(SExp n) {
323:                if (n instanceof  Cons)
324:                    return ((Cons) n).getRest().accept(NameVisitor.ONLY);
325:                else
326:                    throw new PrivateProjectException(
327:                            "List expected, but found text instead");
328:            }
329:
330:            /* nested/inner classes */
331:
332:            /** Parses out a list of file nodes. */
333:            private static class DocFileListVisitor implements 
334:                    SEListVisitor<List<DocFile>> {
335:                /** Base directory for relative paths */
336:                private String _base;
337:
338:                DocFileListVisitor(String base) {
339:                    _base = base;
340:                }
341:
342:                public List<DocFile> forEmpty(Empty e) {
343:                    return new ArrayList<DocFile>();
344:                }
345:
346:                public List<DocFile> forCons(Cons c) {
347:                    List<DocFile> list = c.getRest().accept(this );
348:                    DocFile tmp = ProjectFileParser.ONLY.parseFile(
349:                            c.getFirst(), _base);
350:                    list.add(0, tmp); // add to the end
351:                    return list;
352:                }
353:            };
354:
355:            /** Traverses the list of expressions found after "file" tag and returns the DocFile described by those properties. */
356:            private static class DocFilePropertyVisitor implements 
357:                    SEListVisitor<DocFile> {
358:                private String fname = "";
359:                private Pair<Integer, Integer> select = new Pair<Integer, Integer>(
360:                        new Integer(0), new Integer(0));
361:                private Pair<Integer, Integer> scroll = new Pair<Integer, Integer>(
362:                        new Integer(0), new Integer(0));
363:                private boolean active = false;
364:                private String pack = "";
365:                private Date modDate = null;
366:
367:                private String pathRoot;
368:
369:                public DocFilePropertyVisitor(String pr) {
370:                    pathRoot = pr;
371:                }
372:
373:                public DocFile forCons(Cons c) {
374:                    String name = c.getFirst().accept(NameVisitor.ONLY);
375:                    if (name.compareToIgnoreCase("name") == 0) {
376:                        fname = ProjectFileParser.ONLY.parseFileName(c
377:                                .getFirst());
378:                    } else if (name.compareToIgnoreCase("select") == 0) {
379:                        select = ProjectFileParser.ONLY.parseIntPair(c
380:                                .getFirst());
381:                    } else if (name.compareToIgnoreCase("scroll") == 0) {
382:                        scroll = ProjectFileParser.ONLY.parseIntPair(c
383:                                .getFirst());
384:                    } else if (name.compareToIgnoreCase("active") == 0) {
385:                        active = true;
386:                    } else if (name.compareToIgnoreCase("package") == 0) {
387:                        pack = ProjectFileParser.ONLY.parseStringNode(c
388:                                .getFirst());
389:                    } else if (name.compareToIgnoreCase("mod-date") == 0) {
390:                        String tmp = ProjectFileParser.ONLY.parseStringNode(c
391:                                .getFirst());
392:                        try {
393:                            //attemp parsing in default locale
394:                            modDate = ProjectProfile.MOD_DATE_FORMAT.parse(tmp);
395:                        } catch (java.text.ParseException e1) {
396:                            //parsing in default locale failed
397:                            try {
398:                                //attempt parsing in current locale
399:                                modDate = new SimpleDateFormat(
400:                                        ProjectProfile.MOD_DATE_FORMAT_STRING)
401:                                        .parse(tmp);
402:                            } catch (java.text.ParseException e2) {
403:                                //both parsings failed
404:                                throw new PrivateProjectException(
405:                                        "Bad mod-date: " + e2.getMessage());
406:                            }
407:                        }
408:                    }
409:
410:                    return c.getRest().accept(this );
411:                }
412:
413:                public DocFile forEmpty(Empty c) {
414:                    if (pathRoot == null || new File(fname).isAbsolute()) {
415:                        return new DocFile(fname, select, scroll, active, pack);
416:                    } else {
417:                        DocFile f = new DocFile(pathRoot, fname, select,
418:                                scroll, active, pack);
419:                        if (modDate != null)
420:                            f.setSavedModDate(modDate.getTime());
421:                        return f;
422:                    }
423:                }
424:            }
425:
426:            /** Parses out a list of path nodes into a list of Strings. */
427:            private static class PathListVisitor implements 
428:                    SEListVisitor<List<String>> {
429:                public static final PathListVisitor ONLY = new PathListVisitor();
430:
431:                private PathListVisitor() {
432:                }
433:
434:                public List<String> forEmpty(Empty e) {
435:                    return new ArrayList<String>();
436:                }
437:
438:                public List<String> forCons(Cons c) {
439:                    List<String> list = c.getRest().accept(this );
440:                    SExp first = c.getFirst();
441:                    String name = first.accept(NameVisitor.ONLY);
442:                    if (name.compareToIgnoreCase("path") == 0) {
443:                        String tmp = ProjectFileParser.ONLY.parseStringNode(c
444:                                .getFirst());
445:                        list.add(0, tmp); // add to the end
446:                    }
447:                    return list;
448:                }
449:            };
450:
451:            /** Retrieves the name of a node.  The node should either be a list with its first element being a text atom, 
452:             *  or a text atom itself.
453:             */
454:            private static class NameVisitor implements  SExpVisitor<String> {
455:                public static final NameVisitor ONLY = new NameVisitor();
456:
457:                private NameVisitor() {
458:                }
459:
460:                public String forEmpty(Empty e) {
461:                    throw new PrivateProjectException(
462:                            "Found an empty node, expected a labeled node");
463:                }
464:
465:                public String forCons(Cons c) {
466:                    return c.getFirst().accept(this );
467:                }
468:
469:                public String forBoolAtom(BoolAtom b) {
470:                    throw new PrivateProjectException(
471:                            "Found a boolean, expected a label");
472:                }
473:
474:                public String forNumberAtom(NumberAtom n) {
475:                    throw new PrivateProjectException(
476:                            "Found a number, expected a label");
477:                }
478:
479:                public String forTextAtom(TextAtom t) {
480:                    return t.getText();
481:                }
482:            };
483:
484:            /** Retrieves the number of a node.  The node should either be a list with its first element being a number atom, 
485:             *  or a number atom itself.
486:             */
487:            private static class NumberVisitor implements  SExpVisitor<Integer> {
488:                public static final NumberVisitor ONLY = new NumberVisitor();
489:
490:                private NumberVisitor() {
491:                }
492:
493:                public Integer forEmpty(Empty e) {
494:                    throw new PrivateProjectException(
495:                            "Found an empty node, expected an integer");
496:                }
497:
498:                public Integer forCons(Cons c) {
499:                    return c.getFirst().accept(this );
500:                }
501:
502:                public Integer forBoolAtom(BoolAtom b) {
503:                    throw new PrivateProjectException(
504:                            "Found a boolean, expected an integer");
505:                }
506:
507:                public Integer forNumberAtom(NumberAtom n) {
508:                    return n.intValue();
509:                }
510:
511:                public Integer forTextAtom(TextAtom t) {
512:                    throw new PrivateProjectException("Found a string '" + t
513:                            + "', expected an integer");
514:                }
515:            };
516:
517:            /** Parses out a list of watch names into a list of watches. */
518:            private static class WatchListVisitor implements 
519:                    SEListVisitor<List<DebugWatchData>> {
520:                public static final WatchListVisitor ONLY = new WatchListVisitor();
521:
522:                private WatchListVisitor() {
523:                }
524:
525:                public List<DebugWatchData> forEmpty(Empty e) {
526:                    return new ArrayList<DebugWatchData>();
527:                }
528:
529:                public List<DebugWatchData> forCons(Cons c) {
530:                    List<DebugWatchData> list = c.getRest().accept(this );
531:                    SExp first = c.getFirst();
532:                    String name = first.accept(NameVisitor.ONLY);
533:                    if (name.compareToIgnoreCase("watch") == 0) {
534:                        String tmp = ProjectFileParser.ONLY.parseStringNode(c
535:                                .getFirst());
536:                        list.add(0, new DebugWatchData(tmp)); // add to the end
537:                    }
538:                    return list;
539:                }
540:            };
541:
542:            // === breakpoints ===
543:
544:            /** Parses out a list of breakpoint nodes. */
545:            private class BreakpointListVisitor implements 
546:                    SEListVisitor<List<DebugBreakpointData>> {
547:                public List<DebugBreakpointData> forEmpty(Empty e) {
548:                    return new ArrayList<DebugBreakpointData>();
549:                }
550:
551:                public List<DebugBreakpointData> forCons(Cons c) {
552:                    List<DebugBreakpointData> list = c.getRest().accept(this );
553:                    DebugBreakpointData tmp = ProjectFileParser.ONLY
554:                            .parseBreakpoint(c.getFirst(), _srcFileBase);
555:                    list.add(0, tmp); // add to the end
556:                    return list;
557:                }
558:            };
559:
560:            /** Parses out the labeled node (a non-empty list) into a breakpoint. The node must have the "breakpoint" label on it.
561:             *  @param s the non-empty list expression
562:             *  @return the breakpoint described by this s-expression
563:             */
564:            DebugBreakpointData parseBreakpoint(SExp s, String pathRoot) {
565:                String name = s.accept(NameVisitor.ONLY);
566:                if (name.compareToIgnoreCase("breakpoint") != 0)
567:                    throw new PrivateProjectException(
568:                            "Expected a breakpoint tag, found: " + name);
569:                if (!(s instanceof  Cons))
570:                    throw new PrivateProjectException(
571:                            "Expected a labeled node, found a label: " + name);
572:                SEList c = ((Cons) s).getRest(); // get parameter list
573:
574:                BreakpointPropertyVisitor v = new BreakpointPropertyVisitor(
575:                        pathRoot);
576:                return c.accept(v);
577:            }
578:
579:            /** Traverses the list of expressions found after "breakpoint" tag and returns the Breakpoint described by those properties. */
580:            private static class BreakpointPropertyVisitor implements 
581:                    SEListVisitor<DebugBreakpointData> {
582:                private String fname = null;
583:                private Integer offset = null;
584:                private Integer lineNumber = null;
585:                private boolean isEnabled = false;
586:
587:                private String pathRoot;
588:
589:                public BreakpointPropertyVisitor(String pr) {
590:                    pathRoot = pr;
591:                }
592:
593:                public DebugBreakpointData forCons(Cons c) {
594:                    String name = c.getFirst().accept(NameVisitor.ONLY);
595:                    if (name.compareToIgnoreCase("name") == 0) {
596:                        fname = ProjectFileParser.ONLY.parseFileName(c
597:                                .getFirst());
598:                    } else if (name.compareToIgnoreCase("offset") == 0) {
599:                        offset = ProjectFileParser.ONLY.parseInt(c.getFirst());
600:                    } else if (name.compareToIgnoreCase("line") == 0) {
601:                        lineNumber = ProjectFileParser.ONLY.parseInt(c
602:                                .getFirst());
603:                    } else if (name.compareToIgnoreCase("enabled") == 0) {
604:                        isEnabled = true;
605:                    }
606:
607:                    return c.getRest().accept(this );
608:                }
609:
610:                public DebugBreakpointData forEmpty(Empty c) {
611:                    if ((fname == null) || (offset == null)
612:                            || (lineNumber == null)) {
613:                        throw new PrivateProjectException(
614:                                "Breakpoint information incomplete, need name, offset and line tags");
615:                    }
616:                    if (pathRoot == null || new File(fname).isAbsolute()) {
617:                        final File f = new File(fname);
618:                        return new DebugBreakpointData() {
619:                            public File getFile() {
620:                                return f;
621:                            }
622:
623:                            public int getOffset() {
624:                                return offset;
625:                            }
626:
627:                            public int getLineNumber() {
628:                                return lineNumber;
629:                            }
630:
631:                            public boolean isEnabled() {
632:                                return isEnabled;
633:                            }
634:                        };
635:                    } else {
636:                        final File f = new File(pathRoot, fname);
637:                        return new DebugBreakpointData() {
638:                            public File getFile() {
639:                                return f;
640:                            }
641:
642:                            public int getOffset() {
643:                                return offset;
644:                            }
645:
646:                            public int getLineNumber() {
647:                                return lineNumber;
648:                            }
649:
650:                            public boolean isEnabled() {
651:                                return isEnabled;
652:                            }
653:                        };
654:                    }
655:                }
656:            }
657:
658:            // === bookmarks ===
659:
660:            /** Parses out a list of bookmark nodes. */
661:            private class BookmarkListVisitor implements 
662:                    SEListVisitor<List<DocumentRegion>> {
663:                public List<DocumentRegion> forEmpty(Empty e) {
664:                    return new ArrayList<DocumentRegion>();
665:                }
666:
667:                public List<DocumentRegion> forCons(Cons c) {
668:                    List<DocumentRegion> list = c.getRest().accept(this );
669:                    DocumentRegion tmp = ProjectFileParser.ONLY.parseBookmark(c
670:                            .getFirst(), _srcFileBase);
671:                    list.add(0, tmp); // add to the end
672:                    return list;
673:                }
674:            };
675:
676:            /** Parses out the labeled node (a non-empty list) into a bookmark. The node must have the "bookmark" label on it.
677:             *  @param s the non-empty list expression
678:             *  @return the bookmark described by this s-expression
679:             */
680:            DocumentRegion parseBookmark(SExp s, String pathRoot) {
681:                String name = s.accept(NameVisitor.ONLY);
682:                if (name.compareToIgnoreCase("bookmark") != 0)
683:                    throw new PrivateProjectException(
684:                            "Expected a bookmark tag, found: " + name);
685:                if (!(s instanceof  Cons))
686:                    throw new PrivateProjectException(
687:                            "Expected a labeled node, found a label: " + name);
688:                SEList c = ((Cons) s).getRest(); // get parameter list
689:
690:                BookmarkPropertyVisitor v = new BookmarkPropertyVisitor(
691:                        pathRoot);
692:                return c.accept(v);
693:            }
694:
695:            /** Traverses the list of expressions found after "bookmark" tag and returns the DocumentRegion
696:             *  described by those properties. */
697:            private static class BookmarkPropertyVisitor implements 
698:                    SEListVisitor<DocumentRegion> {
699:                private String fname = null;
700:                private Integer startOffset = null;
701:                private Integer endOffset = null;
702:
703:                private String pathRoot;
704:
705:                public BookmarkPropertyVisitor(String pr) {
706:                    pathRoot = pr;
707:                }
708:
709:                public DocumentRegion forCons(Cons c) {
710:                    String name = c.getFirst().accept(NameVisitor.ONLY);
711:                    if (name.compareToIgnoreCase("name") == 0) {
712:                        fname = ProjectFileParser.ONLY.parseFileName(c
713:                                .getFirst());
714:                    } else if (name.compareToIgnoreCase("start") == 0) {
715:                        startOffset = ProjectFileParser.ONLY.parseInt(c
716:                                .getFirst());
717:                    } else if (name.compareToIgnoreCase("end") == 0) {
718:                        endOffset = ProjectFileParser.ONLY.parseInt(c
719:                                .getFirst());
720:                    }
721:
722:                    return c.getRest().accept(this );
723:                }
724:
725:                public DocumentRegion forEmpty(Empty c) {
726:                    if ((fname == null) || (startOffset == null)
727:                            || (endOffset == null)) {
728:                        throw new PrivateProjectException(
729:                                "Bookmark information incomplete, need name, start offset and end offset");
730:                    }
731:                    File f;
732:                    if (pathRoot == null || new File(fname).isAbsolute()) {
733:                        f = new File(fname);
734:                    } else {
735:                        f = new File(pathRoot, fname);
736:                    }
737:                    return new SimpleDocumentRegion(null, f, startOffset,
738:                            endOffset);
739:                }
740:            }
741:
742:            private static class PrivateProjectException extends
743:                    RuntimeException {
744:                public PrivateProjectException(String message) {
745:                    super(message);
746:                }
747:            }
748:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.