001: /*
002: * Tracker.java February 2006
003: *
004: * Copyright (C) 2006, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.page.translate;
022:
023: import simple.page.Workspace;
024: import java.util.ArrayList;
025: import java.util.List;
026: import java.io.File;
027:
028: /**
029: * The <code>Tracker</code> is used to keep track of files within
030: * the project source directory. This allows the compiler to perform
031: * background compilation, such that a translated and compiled JSP
032: * file can be monitored for changes. Should a change occur the
033: * JSP can be translated and compiled with any modifications. This
034: * also performs its checks in a way that allows multiple contexts
035: * to be used. This allows JSP files to be overridden by simply
036: * changing the context it lives within.
037: * <p>
038: * As well as allowing the compiler to determine when modifications
039: * are made to the source JSP, this will allow the generator to
040: * determine the JSP source files included within the root file.
041: * This allows, informative comments to be embedded.
042: *
043: * @author Niall Gallagher
044: */
045: class Tracker implements Reference {
046:
047: /**
048: * Provides the file system view for the JSP translation.
049: */
050: private Workspace project;
051:
052: /**
053: * Keeps track of all modification times for included files.
054: */
055: private List history;
056:
057: /**
058: * Maintains a list of the JSP source files that are used.
059: */
060: private List include;
061:
062: /**
063: * Constructor for the <code>Tracker</code> object. This is used
064: * to keep track of the JSP files and its includes. The project is
065: * provided to allow this object to monitor modification times for
066: * root JSP and the sources it includes.
067: *
068: * @param project this is the workspace used to locate the files
069: */
070: public Tracker(Workspace project) {
071: this .include = new ArrayList();
072: this .history = new ArrayList();
073: this .project = project;
074: }
075:
076: /**
077: * This provides the list of JSP files that be been used to compose
078: * the resulting source. The included files are identified using
079: * a URI path that references a file from the <code>Context</code>
080: * used. This allows a cascading context to search for the file,
081: * such that the file can move and change context, allowing the
082: * translator and compiler to initiate compilation again.
083: *
084: * @return this returns a list of URI paths for JSP includes
085: */
086: public List getIncludes() {
087: return include;
088: }
089:
090: /**
091: * This is used to include other JSP files or text files, which
092: * can be translated and compiled into the resulting source. The
093: * included file is monitored by the JSP engine so that if the
094: * file changes it can be compiled back in to the source.
095: * <p>
096: * All included files must be absolute so that its details can
097: * be retrieved using a <code>Context</code> object. This allows
098: * the modification times for the source to be determined.
099: *
100: * @param path an absolute path to the included JSP file
101: */
102: public void addInclude(String path) {
103: addInclude(path, getFile(path));
104: }
105:
106: /**
107: * This is used to include other JSP files or text files, which
108: * can be translated and compiled into the resulting source. The
109: * included file is monitored by the JSP engine so that if the
110: * file changes it can be compiled back in to the source.
111: * <p>
112: * All included files must be absolute so that its details can
113: * be retrieved using a <code>Context</code> object. This allows
114: * the modification times for the source to be determined.
115: *
116: * @param path an absolute path to the included JSP file
117: * @param file this is an initial reference to the JSP file
118: */
119: private void addInclude(String path, File file) {
120: include.add(new Entry(path, file));
121: history.add(path);
122: }
123:
124: /**
125: * This will acquire a <code>File</code> for the specified URI
126: * path. This is used so that if there are multiple contexts
127: * then the file reference can change, thus allowing the JSP
128: * to be translated and compiled from a new location.
129: *
130: * @param path this is the URI path used to reference the JSP
131: *
132: * @return this is the file reference pointing to the JSP
133: */
134: private File getFile(String path) {
135: return project.getSourceFile(path);
136: }
137:
138: /**
139: * This checks if the source or its includes have expired. This
140: * will check the JSP and its includes to determine if the
141: * source has changed in any way. For background compilation
142: * this method can be used to refresh the pages to ensure that
143: * the most up to date code is active.
144: *
145: * @return this returns true if any of the JSP files changed
146: */
147: public boolean isModified() {
148: for (int i = 0; i < include.size(); i++) {
149: Entry file = (Entry) include.get(i);
150:
151: if (file.isModified()) {
152: return true;
153: }
154: }
155: return false;
156: }
157:
158: /**
159: * This is used to determine whether the source files have
160: * been deleted. This is useful when a page should be purged
161: * from the system. A deletion of the file will allow memory
162: * to be freed from the VM and ensures it does not resolve.
163: *
164: * @return true if any of the JSP files were deleted
165: */
166: public boolean isDeleted() {
167: for (int i = 0; i < include.size(); i++) {
168: Entry file = (Entry) include.get(i);
169:
170: if (file.isDeleted()) {
171: return true;
172: }
173: }
174: return false;
175: }
176:
177: /**
178: * The <code>Entry</code> object is used to keep track of the JSP
179: * file modification times. This ensures that should the source
180: * change this will indicate it. This reacquires the file each
181: * time the <code>Reference.isModified</code> is invoked ensuring
182: * that JSP can be housed in, or moved to, a separate context.
183: *
184: * @see simple.page.Workspace
185: */
186: private class Entry {
187:
188: /**
189: * This is the URI path used to reference the JSP source.
190: */
191: public String path;
192:
193: /**
194: * Keeps a time stamp for the modification time of the JSP.
195: */
196: public long stamp;
197:
198: /**
199: * Allows deletion of the JSP can unload the page class.
200: */
201: public boolean exist;
202:
203: /**
204: * Constructor for the <code>Entry</code> object. This is used
205: * to keep track of the JSP sources, and ensures any changes
206: * will allow the engine to translate and compile the source
207: * with the most up to date version.
208: *
209: * @param path this is the URI path used to target the file
210: * @param file this is used to capture a snapshot of the file
211: */
212: public Entry(String path, File file) {
213: this .stamp = file.lastModified();
214: this .exist = file.exists();
215: this .path = path;
216: }
217:
218: /**
219: * This is used to determine whether the source JSP has been
220: * modified. This allows each file used to compose the page
221: * to be monitored to determine when to refresh the page.
222: * This is also true if the file has been deleted.
223: *
224: * @return this returns true if the JSP file has changed
225: */
226: public boolean isModified() {
227: File file = getFile(path);
228:
229: if (exist != file.exists()) {
230: return true;
231: }
232: if (stamp != file.lastModified()) {
233: return true;
234: }
235: return false;
236: }
237:
238: /**
239: * This is used to determine whether the source JSP has been
240: * deleted. This allows the file to be purged from the system
241: * if it has been deleted from the file system. If the JSP
242: * file has changed context this will still return true.
243: *
244: * @return this returns true if the file has been deleted
245: */
246: public boolean isDeleted() {
247: File file = getFile(path);
248:
249: if (exist != file.exists()) {
250: return true;
251: }
252: return false;
253: }
254: }
255: }
|