001: ///////////////////////////////
002: // Makumba, Makumba tag library
003: // Copyright (C) 2000-2003 http://www.makumba.org
004: //
005: // This library is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU Lesser General Public
007: // License as published by the Free Software Foundation; either
008: // version 2.1 of the License, or (at your option) any later version.
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 GNU
013: // Lesser General Public License for more details.
014: //
015: // You should have received a copy of the GNU Lesser General Public
016: // License along with this library; if not, write to the Free Software
017: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: //
019: // -------------
020: // $Id: SyntaxPoint.java 1600 2007-09-17 17:06:30Z manuel_gay $
021: // $Name$
022: /////////////////////////////////////
023:
024: package org.makumba.analyser.engine;
025:
026: /**
027: * Keeps track of important points in a file. Syntax points are typically stored in a sorted set, and used for syntax
028: * colouring. A syntax colourer would load the file, then go through the syntax points and change the coloring context
029: * at each syntax point. This is an abstract class, but can be easily instantiated with an anonymous inner class like
030: * this: SyntaxPoint comment=new SyntaxPoint(position) { public String getType(){ return "JSPcomment";}};
031: *
032: * idea: the class can also find identifiers in the text and ask the owners of other enclosing syntax points (or the
033: * owner of the whole text info) if they can account for them. For example in the case of a makumba JSP, a LIST tag can
034: * account for a OQL label, an MDD field, a MDD name or a $attribute). If yes, syntax points are produced by the
035: * respective entity, and presented in different colours or as links
036: *
037: * idea: a syntax point walker that goes through a text and invokes methods of a syntax colourer like beginText(),
038: * beginJSPComment, endJspComment, beginTag... etc
039: *
040: * @author Cristian Bogdan
041: * @version $Id: SyntaxPoint.java 1600 2007-09-17 17:06:30Z manuel_gay $
042: */
043: public abstract class SyntaxPoint implements Comparable {
044: /**
045: * Default constructor
046: *
047: * @param position
048: * the position of this SyntaxPoint
049: * @param begin
050: * is this SyntaxPoint the beginning
051: */
052: public SyntaxPoint(int position, boolean begin) {
053: this .position = position;
054: this .begin = begin;
055: }
056:
057: /** Simpler constructor */
058: public SyntaxPoint(int position) {
059: this .position = position;
060: this .begin = true;
061: }
062:
063: /**
064: * Gets the position in the file
065: *
066: * @return the position in the file
067: */
068: public int getPosition() {
069: return position;
070: }
071:
072: /**
073: * Gets the offset by which this SyntaxPoint has moved from the original position due to includes
074: *
075: * @return the offset caused by inclusions
076: */
077: public int getIncludeOffset() {
078: return offset;
079: }
080:
081: public int getOriginalPosition() {
082: return getPosition() - getIncludeOffset();
083: }
084:
085: /**
086: * Gets the line number in the file
087: *
088: * @retun the line number in the file
089: */
090: public int getLine() {
091: return line;
092: }
093:
094: /**
095: * Gets the column number in the file
096: *
097: * @return the column number in the file
098: */
099: public int getColumn() {
100: return column;
101: }
102:
103: /**
104: * This is a temporary workaround for '@included' files not having their syntaxpoints & offsets detected correctly.
105: *
106: * @param lineLength
107: * the length of the line
108: * @return the correct column
109: */
110: public int getOriginalColumn(int lineLength) {
111: if (getColumn() > lineLength + 1) {
112: return getColumn() - getIncludeOffset();
113: } else {
114: return getColumn();
115: }
116: }
117:
118: /**
119: * Checks whether this this point is the beginning of the end of something. Ends are stored one position after the
120: * last character of the entity so substring() works right away
121: *
122: * @return <code>true</code> if this is a beginning, <code>false</code> otherwise
123: */
124: public boolean isBegin() {
125: return begin;
126: }
127:
128: /** The type of this point, will be defined by the subclass */
129: public abstract String getType();
130:
131: /** Additional information which can be returned by subclasses */
132: public Object getOtherInfo() {
133: return null;
134: }
135:
136: /** The file that contains this point */
137: public java.io.File getFile() {
138: return sourceFile.file;
139: }
140:
141: /**
142: * Makes an end for a given syntax point
143: *
144: * @param begin
145: * the begin SyntaxPoint
146: * @param position
147: * the position of the end
148: */
149: static public SyntaxPoint makeEnd(SyntaxPoint begin, int position) {
150: return new End(begin, position);
151: }
152:
153: /** The position in the file */
154: int position;
155:
156: /** The offset sufferred due to includes */
157: int offset = 0;
158:
159: /**
160: * Adjusts the offset and position at inclusion of a file
161: *
162: * @param delta
163: * the length of the included file
164: */
165: void moveByInclude(int delta) {
166: position += delta;
167: offset += delta;
168: }
169:
170: /** Is this point a begin or an end of something (where applicable) */
171: boolean begin;
172:
173: /** Redundant but useful data: line of the position in the text */
174: int line;
175:
176: /** Redundant but useful data: column of the position in the text */
177: int column;
178:
179: /** The file in which this syntax point was detected */
180: SourceSyntaxPoints sourceFile;
181:
182: /**
183: * Compares two objects, for sorting in the syntaxPoints collection
184: *
185: * @param o
186: * object to be compared with
187: * @return -1 if this is before, 1 if after
188: */
189: public int compareTo(Object o) {
190: SyntaxPoint sp = (SyntaxPoint) o;
191: int n = position - sp.position;
192:
193: if (n != 0) // order by position
194: return n;
195:
196: if (begin == sp.begin) /*
197: * two things begin at the same place? strange. but possible, e.g. lines can begin or
198: * end at the same place where tags begin or end. at some point there should be a
199: * special case here for lines begins and ends to be before, respectively after anything
200: * else.
201: */
202: {
203: if (sp.getType().equals("TextLine"))
204: return sp.begin ? 1 : -1;
205: if (getType().equals("TextLine"))
206: return begin ? -1 : 1;
207: return getType().compareTo(sp.getType()); // a random, really...
208: }
209:
210: // the thing that begins must come after the thing that ends
211: return begin ? 1 : -1;
212: }
213:
214: /**
215: * Performs a simple comparison, for hashing reasons
216: *
217: * @param o
218: * the object to be compared with
219: * @return <code>true</code> if the two objects are equal, <code>false</code> otherwise
220: */
221: public boolean equals(Object o) {
222: SyntaxPoint sp = (SyntaxPoint) o;
223: return sp != null && position == sp.position
224: && begin == sp.begin && getType() == sp.getType();
225: }
226:
227: /**
228: * Generates the hashcode of the SyntaxPoint
229: *
230: * @return The computed hashcode
231: */
232: public int hashCode() {
233: return position * getType().hashCode() * (begin ? 1 : -1);
234: }
235:
236: /**
237: * Prints the position and type of the SyntaxPoint, for debugging
238: *
239: * @return A String that can be used for debugging
240: */
241: public String toString() {
242: return "" + position + ":"
243: + (begin ? "<" + getType() : getType() + ">");
244: }
245:
246: /**
247: * A simple implementation: ends of strings marked by other syntax points
248: *
249: * @author Cristian Bogdan
250: */
251: public static class End extends SyntaxPoint {
252: SyntaxPoint _begin;
253:
254: /** constructor */
255: public End(SyntaxPoint begin, int position) {
256: super (position, false);
257: this ._begin = begin;
258: }
259:
260: /** returns the begining */
261: public Object getOtherInfo() {
262: return _begin;
263: }
264:
265: /** returns same type as the begining */
266: public String getType() {
267: return _begin.getType();
268: }
269: }
270:
271: }
|