001: /*
002: * Target.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.util.parse.ParseBuffer;
024: import simple.util.parse.Parser;
025: import simple.page.Workspace;
026:
027: /**
028: * The <code>Target</code> object is used to parse the JSP path name
029: * so that a package and class name can be created. The translator
030: * uses the path of the JSP to construct class properties, for example
031: * take the JSP path "/some/path/Source.jsp" this will be used to
032: * create the package name "some.path" and the class "SourcePage"
033: *
034: * @author Niall Gallagher
035: */
036: class Target extends Parser {
037:
038: /**
039: * This is the target is the fully qualified class name.
040: */
041: private ParseBuffer target;
042:
043: /**
044: * This represents the name of the class minus the package.
045: */
046: private ParseBuffer name;
047:
048: /**
049: * This object is used to gather the characters for the package.
050: */
051: private ParseBuffer scope;
052:
053: /**
054: * This is used to store the directory the JSP file is in.
055: */
056: private ParseBuffer path;
057:
058: /**
059: * This is the name of the JSP project workspace object.
060: */
061: private String prefix;
062:
063: /**
064: * Constructor for the <code>Target</code> object. This will create
065: * several buffers used to store the attributes for the target
066: * page class. These buffers are used to accumulate characters.
067: *
068: * @param project this is the JSP project workspace instance
069: */
070: public Target(Workspace project) {
071: this .target = new ParseBuffer();
072: this .name = new ParseBuffer();
073: this .path = new ParseBuffer();
074: this .scope = new ParseBuffer();
075: this .prefix = project.getName();
076: }
077:
078: /**
079: * Constructor for the <code>Target</code> object. This will create
080: * several buffers used to store the attributes for the target
081: * page class. These buffers are used to accumulate characters.
082: *
083: * @param path this is the target path string that is to be parsed
084: * @param project this is the JSP project workspace instance
085: */
086: public Target(Workspace project, String path) {
087: this (project);
088: parse(path);
089: }
090:
091: /**
092: * The provides the name of the resulting object. This is used by
093: * the code generator to determine the correct class name and
094: * constructor to use, and may be used by the source compiler.
095: *
096: * @return this returns the name of the source object generated
097: */
098: public String getName() {
099: return name.toString();
100: }
101:
102: /**
103: * Provides the fully qualified package name for the resulting
104: * object. This is required by the compiler, so that once the
105: * generated source has been compiled it can later be loaded as a
106: * class by the compiler class loader and instantiated.
107: *
108: * @return this returns the fully qualified class name targeted
109: */
110: public String getTarget() {
111: return target.toString();
112: }
113:
114: /**
115: * This is used by the source code generator to determine the
116: * package the target object is using. This ensures that a correct
117: * name space is given to each source, which avoids collisions.
118: *
119: * @return this returns the package name for the source object
120: */
121: public String getPackage() {
122: return scope.toString();
123: }
124:
125: /**
126: * This acquires the directory the source object is generated into.
127: * This allows the generator to create the appropriate directory,
128: * before generating the resulting Java or Groovy object into that
129: * directory before compilation can proceed. This is a URI path.
130: *
131: * @return the directory to generate the source object into
132: */
133: public String getDirectory() {
134: return path.toString();
135: }
136:
137: /**
138: * This will construct a path using the targeted JSP path and the
139: * JSP project workspace name, if one is provided. The path is
140: * typically a resource that can be acquired from the workspace,
141: * however the target is given a prefix of the workspace name. So
142: * if the target is "/demo/File.jsp" the augmented target would
143: * be "/example/demo/File.jsp" if the workspace name was "example".
144: *
145: * @param path this is the path to be parsed for targeted JSP
146: */
147: public void parse(String path) {
148: if (prefix != null) {
149: path = "/" + prefix + path;
150: }
151: super .parse(path);
152: }
153:
154: /**
155: * This method is used to parse each individual part of the target
156: * including the name, package, and directory of the source object.
157: * Once this has completed each part of the target will be
158: * buffered within the individual buffers of this object.
159: */
160: protected void parse() {
161: name();
162: path();
163: scope();
164: target();
165: }
166:
167: /**
168: * This will clear the target tokens so that this can be reused
169: * by the builder. In practice this method just satisfies the
170: * contract of the token so that this object is not abstract.
171: */
172: protected void init() {
173: name.clear();
174: scope.clear();
175: path.clear();
176: target.clear();
177: off = 0;
178: }
179:
180: /**
181: * This will extract the directory specified in the target path.
182: * This is basically all path segments up the, but not including,
183: * the name of the JSP. For example "/some/path/File.jsp" this
184: * will extract the value "/some/path/".
185: */
186: public void path() {
187: if (buf[off] != '/') {
188: path.append('/');
189: }
190: path.append(buf, off, count + 1);
191: }
192:
193: /**
194: * This is used to concatenate the package name and the class name
195: * extracted from the target path. If there is no package, that is
196: * if the file is within the root directory, no package is used.
197: */
198: public void target() {
199: if (scope.length() > 0) {
200: target.append(scope);
201: target.append(".");
202: }
203: target.append(name);
204: }
205:
206: /**
207: * This is used to extract the name of the class from the name of
208: * the JSP file. For example if the path was "/example/File.jsp"
209: * then the resulting class name generated would be "FilePage".
210: */
211: public void name() {
212: int len = 0;
213:
214: while (count-- > off) {
215: if (buf[count] == '/') {
216: break;
217: }
218: if (buf[count] == '.') {
219: len = 0;
220: } else {
221: len++;
222: }
223: }
224: name.append(buf, count + 1, len);
225: name.append("Page");
226: }
227:
228: /**
229: * This is used to extract the package name of the target. This is
230: * basically the target directory with '/' characters replaced with
231: * '.' characters. All '/' characters except for the root are
232: * converted to a '.' delimited list of the path segments.
233: */
234: public void scope() {
235: int pos = count;
236: int len = 0;
237:
238: while (pos-- > off) {
239: if (buf[pos] == '/') {
240: if (pos == off) {
241: off++;
242: break;
243: }
244: buf[pos] = '.';
245: }
246: len++;
247: }
248: scope.append(buf, off, len);
249: }
250: }
|