View Javadoc

1   //$Id: UserCodeParser.java,v 1.3 2007/07/13 13:18:29 kameleono Exp $
2   
3   package net.sourceforge.sql2java;
4   
5   import java.io.BufferedReader;
6   import java.io.File;
7   import java.io.FileReader;
8   import java.util.Enumeration;
9   import java.util.Hashtable;
10  
11  /**
12   * Parses an existing source file for special sql2code comment blocks.
13   * <br>
14   * Stores the source code that it finds in between those blocks in a
15   * hashtable. This allows CodeWriter classes to rewrite existing files
16   * while preserving code written by the user.
17   *
18   * @author James Cooper <pixel@bitmechanic.com>
19   * @version $Id: UserCodeParser.java,v 1.3 2007/07/13 13:18:29 kameleono Exp $
20   */
21  public class UserCodeParser {
22  
23      private static final String START = "// ";
24      private static final String BLOCK_BEGIN = "+";
25      private static final String BLOCK_END = "-";
26  
27      private String LINE_SEP = System.getProperty("line.separator");
28      private Hashtable codeHash;
29      private String filename;
30      private boolean isNew;
31  
32      /**
33       * Constructs a new parser, and tells the parser to try to load the
34       * given filename.
35       * <br>
36       * If the file does not exist, the parser will simply initialize a
37       * new hashtable internally, and the get methods on the parser will
38       * return new comment blocks (with nothing in between them).
39       *
40       * @param filename Full path to the existing file to parse.
41       * @throws Exception if the existing file exists, but cannot be read,
42       *         or if there is an error while reading the file
43       */
44      public UserCodeParser(String filename) throws Exception {
45          parse(filename);
46      }
47  
48      /**
49       * Returns the filename associated with this parser.
50       */
51      public String getFilename() { return filename; }
52  
53      /**
54       * Returns true if the file to parse did not exist.
55       */
56      public boolean isNew() { return isNew; }
57  
58      /**
59       * Parses the file passed in.
60       */
61      public void parse(String parsedFileName) throws Exception {
62          codeHash = new Hashtable();
63          boolean inBlock = false;
64          String blockName = null;
65          StringBuffer code = new StringBuffer();
66          isNew = true;
67  
68          File file = new File(parsedFileName);
69          if(file.exists()) {
70              filename = parsedFileName;
71              isNew = false;
72              BufferedReader reader = new BufferedReader(new FileReader(file));
73              String line = reader.readLine();
74              while(line != null) {
75                  if(inBlock) code.append(line).append(LINE_SEP);
76  
77                  if(line.indexOf(START) != -1) {
78                      if(inBlock) {
79                          if(line.equals(START + blockName + BLOCK_END)) {
80  
81                              // Done parsing block.  Store it
82                              codeHash.put(blockName, code.toString());
83                              inBlock = false;
84                          }
85                      }
86                      else {
87                          blockName = parseName(line);
88                          if(!blockName.equals("")) {
89                              inBlock = true;
90                              code.setLength(0);
91                              code.append(line).append(LINE_SEP);
92                          }
93                      }
94                  }
95  
96                  line = reader.readLine();
97              }
98              reader.close();
99          }
100     }
101 
102     private String parseName(String line) {
103         int startPos = line.indexOf(START);
104         if(startPos == -1) return "";
105         startPos += START.length();
106 
107         if(startPos >= (line.length() + 1)) return "";
108 
109         int endPos = line.lastIndexOf(BLOCK_BEGIN, startPos);
110         if(endPos != line.length()-BLOCK_BEGIN.length()) return "";
111         else  {
112             String name = line.substring(startPos, endPos);
113             return name.trim();
114         }
115     }
116 
117     /**
118      * Returns true if there is a block with the given name in the
119      * existing file that was parsed, otherwise returns false.
120      *
121      * @param name Name of the code block to check for.
122      */
123     public boolean hasBlock(String name) {
124         return codeHash.get(name) != null;
125     }
126 
127     /**
128      * Returns the comment+code block associated with this name.
129      * <br>
130      * If the name is not found in the parsed file, this returns a new
131      * comment block with no code inside it.
132      *
133      * @param name Name of the code block to return.
134      */
135     public String getBlock(String name) {
136         String code = null;
137         if (name != null) code = (String)codeHash.get(name);
138         if(code == null) {
139             code = generateNewBlock(name);
140             codeHash.put(name, code);
141         }
142         return code;
143     }
144 
145     /**
146      * Returns an array of the block names parsed in the existing file.
147      * <br>
148      * If the file did not exist, or if there are no blocks in the file,
149      * a zero length array is returned.
150      */
151     public String[] getBlockNames() {
152         String list[] = new String[codeHash.size()];
153         int i = 0;
154         for(Enumeration e = codeHash.keys(); e.hasMoreElements(); ) {
155             list[i++] = (String)e.nextElement();
156         }
157 
158         return list;
159     }
160 
161     /**
162      * Generates a new code block with this name.
163      */
164     private String generateNewBlock(String name) {
165         StringBuffer str = new StringBuffer(512);
166         str.append(START);
167         str.append(name);
168         str.append(BLOCK_BEGIN);
169         str.append(LINE_SEP).append(LINE_SEP);
170         str.append(START);
171         str.append(name);
172         str.append(BLOCK_END);
173 
174         return str.toString();
175     }
176 }