1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.ant.sniplet;
21
22 import org.apache.tools.ant.BuildException;
23 import org.apache.tools.ant.DirectoryScanner;
24 import org.apache.tools.ant.Task;
25 import org.apache.tools.ant.Project;
26 import org.apache.tools.ant.types.FileSet;
27
28 import java.util.regex.Pattern;
29 import java.util.regex.Matcher;
30 import java.util.List;
31 import java.util.ArrayList;
32 import java.io.File;
33 import java.io.LineNumberReader;
34 import java.io.FileReader;
35 import java.io.FileNotFoundException;
36 import java.io.IOException;
37 import java.io.PrintWriter;
38 import java.io.FileOutputStream;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public class CodeSnipletExtractTask extends Task {
67
68 private List<CodeSniplet> sniplets;
69 private List<FileSet> fileSets;
70 private Pattern startPattern;
71 private Pattern endPattern;
72 private File outputDir;
73 private String outputFileNamePattern;
74 private boolean stripLeadingSpaces;
75
76 public void init() throws BuildException {
77 startPattern = Pattern.compile(".*code-sniplet-start\\s*id\\s*=\\s*\"(\\w*)\".*");
78 endPattern = Pattern.compile(".*code-sniplet-end\\s*id\\s*=\\s*\"(\\w*)\".*");
79 this.sniplets = new ArrayList<CodeSniplet>();
80 this.fileSets = new ArrayList<FileSet>();
81 }
82
83 public String getOutputFileNamePattern() {
84 return outputFileNamePattern;
85 }
86
87 public void setOutputFileNamePattern(String outputFileNamePattern) {
88 this.outputFileNamePattern = outputFileNamePattern;
89 }
90
91 public File getOutputDir() {
92 return outputDir;
93 }
94
95 public void setOutputDir(File outputDir) {
96 this.outputDir = outputDir;
97 }
98
99 public void addConfiguredFileSet(FileSet fileSet) {
100 this.fileSets.add(fileSet);
101 }
102
103 public boolean isStripLeadingSpaces() {
104 return stripLeadingSpaces;
105 }
106
107 public void setStripLeadingSpaces(boolean stripLeadingSpaces) {
108 this.stripLeadingSpaces = stripLeadingSpaces;
109 }
110
111 public void execute() throws BuildException {
112 for (int k = 0; k < fileSets.size(); k++) {
113 FileSet fileSet = fileSets.get(k);
114 DirectoryScanner dirScanner = fileSet.getDirectoryScanner(getProject());
115 dirScanner.scan();
116 String[] includedFiles = dirScanner.getIncludedFiles();
117 for (int i = 0; i < includedFiles.length; i++) {
118 String fileS = includedFiles[i];
119 LineNumberReader in = null;
120 try {
121 in = new LineNumberReader(new FileReader(fileSet.getDir(getProject())
122 + File.separator + fileS));
123 String line = in.readLine();
124 while (line != null) {
125 Matcher startMatcher = startPattern.matcher(line);
126 if (startMatcher.matches()) {
127 startSniplet(startMatcher.group(1), fileS, in.getLineNumber());
128 } else {
129 Matcher endMatcher = endPattern.matcher(line);
130 if (endMatcher.matches()) {
131 endSniplet(endMatcher.group(1), fileS, in.getLineNumber());
132 } else {
133 addLine(line);
134 }
135 }
136 line = in.readLine();
137 }
138 for (int j = 0; j < sniplets.size(); j++) {
139 CodeSniplet codeSniplet = (CodeSniplet) sniplets.get(j);
140 if (codeSniplet.getLineEnd() == 0) {
141 codeSniplet.setLineEnd(in.getLineNumber());
142 log("Unclosed sniplet '" + codeSniplet.getId() + "' in file '" + codeSniplet.getFileName() + "' at line '"
143 + codeSniplet.getLineStart() + "'. Forcing close", Project.MSG_WARN);
144 }
145 }
146 createOutput();
147 sniplets = new ArrayList<CodeSniplet>();
148 } catch (IOException e) {
149 throw new BuildException(e);
150 } finally {
151 if (in != null) {
152 try {
153 in.close();
154 } catch (IOException e) {
155 throw new BuildException(e);
156 }
157 }
158 }
159 }
160 }
161 }
162
163 private void createOutput() throws FileNotFoundException {
164 for (int i = 0; i < sniplets.size(); i++) {
165 CodeSniplet codeSniplet = (CodeSniplet) sniplets.get(i);
166 String fileName = codeSniplet.getId() + ".snip";
167 File file = new File(outputDir, fileName);
168 PrintWriter out = new PrintWriter(new FileOutputStream(file));
169 StringBuffer code = codeSniplet.getCode(stripLeadingSpaces);
170 out.print(code);
171 out.close();
172 log("Wrote: " + file.getName(), Project.MSG_INFO);
173 }
174 }
175
176 private void startSniplet(String id, String fileName, int lineNumber) {
177 for (int i = 0; i < sniplets.size(); i++) {
178 CodeSniplet codeSniplet = (CodeSniplet) sniplets.get(i);
179 if (codeSniplet.getId().equals(id)) {
180 throw new BuildException("Duplicate sniplet declaration '" + id + "' in file '" + fileName + "' at line '"
181 + lineNumber + "'. First declaration was in file '" + codeSniplet.getFileName() + "' at line '"
182 + codeSniplet.getLineStart() + "'.");
183 }
184 }
185 CodeSniplet codeSniplet = new CodeSniplet(id, fileName, lineNumber);
186 sniplets.add(codeSniplet);
187 }
188
189 private void endSniplet(String id, String fileName, int lineNumber) {
190 for (int i = 0; i < sniplets.size(); i++) {
191 CodeSniplet codeSniplet = (CodeSniplet) sniplets.get(i);
192 if (codeSniplet.getId().equals(id)) {
193 codeSniplet.setLineEnd(lineNumber);
194 return;
195 }
196 }
197 throw new BuildException("No start of sniplet '" + id + "' in file '" + fileName + "' at line '" + lineNumber
198 + "' found.");
199 }
200
201 private void addLine(String line) {
202 for (int i = 0; i < sniplets.size(); i++) {
203 CodeSniplet codeSniplet = (CodeSniplet) sniplets.get(i);
204 if (codeSniplet.getLineEnd() == 0) {
205 codeSniplet.addLine(line);
206 log("Adding: " + line + " -> " + codeSniplet.getFileName() + ":" + codeSniplet.getId(), Project.MSG_DEBUG);
207 }
208 }
209 }
210
211 }