Source Code Cross Referenced for ReducedModelControl.java in  » IDE » DrJava » edu » rice » cs » drjava » model » definitions » reducedmodel » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » DrJava » edu.rice.cs.drjava.model.definitions.reducedmodel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*BEGIN_COPYRIGHT_BLOCK
002:         *
003:         * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004:         * All rights reserved.
005:         * 
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions are met:
008:         *    * Redistributions of source code must retain the above copyright
009:         *      notice, this list of conditions and the following disclaimer.
010:         *    * Redistributions in binary form must reproduce the above copyright
011:         *      notice, this list of conditions and the following disclaimer in the
012:         *      documentation and/or other materials provided with the distribution.
013:         *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014:         *      names of its contributors may be used to endorse or promote products
015:         *      derived from this software without specific prior written permission.
016:         * 
017:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020:         * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028:         *
029:         * This software is Open Source Initiative approved Open Source Software.
030:         * Open Source Initative Approved is a trademark of the Open Source Initiative.
031:         * 
032:         * This file is part of DrJava.  Download the current version of this project
033:         * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034:         * 
035:         * END_COPYRIGHT_BLOCK*/
036:
037:        package edu.rice.cs.drjava.model.definitions.reducedmodel;
038:
039:        import java.util.Vector;
040:
041:        import edu.rice.cs.util.UnexpectedException;
042:
043:        /** This class provides an implementation of the BraceReduction interface for brace matching.  In order to correctly
044:         * match, this class keeps track of what is commented (line and block) and what is inside double quotes and keeps 
045:         * this in mind when matching.  To avoid unnecessary complication, this class maintains a few invariants for its 
046:         * consistent states, i.e., between top-level function calls.
047:         * <ol>
048:         * <li> The cursor offset is never at the end of a brace.  If movement or insertion puts it there, the cursor is 
049:         * updated to point to the 0 offset of the next brace.
050:         * <li> Quoting information is invalid inside valid comments.  When part of the document becomes uncommented, the
051:         * reduced model must update the quoting information linearly in the newly revealed code.
052:         * <li> Quote shadowing and comment shadowing are mutually exclusive.
053:         * <li> There is no nesting of comment open characters. If // is encountered in the middle of a comment, it is 
054:         * treated as two separate slashes.  Similar for /*.
055:         * </ol>
056:         * All of the code in the class assumes that a lock on this is held.
057:         * @author JavaPLT
058:         * @version $Id: ReducedModelControl.java 4255 2007-08-28 19:17:37Z mgricken $
059:         */
060:        public class ReducedModelControl implements  BraceReduction {
061:            /* private fields; default visibility for testing purposes only. */
062:            volatile ReducedModelBrace _rmb;
063:            volatile ReducedModelComment _rmc;
064:            volatile int _offset;
065:
066:            // Relying on default constructor
067:            //  public ReducedModelControl() {
068:            //    rmb = new ReducedModelBrace(this);
069:            //    rmc = new ReducedModelComment();
070:            //  }
071:
072:            private ReducedModelBrace getRMB() {
073:                if (_rmb == null)
074:                    _rmb = new ReducedModelBrace(this );
075:                return _rmb;
076:            }
077:
078:            private ReducedModelComment getRMC() {
079:                if (_rmc == null)
080:                    _rmc = new ReducedModelComment();
081:                return _rmc;
082:            }
083:
084:            public void insertChar(char ch) {
085:                getRMB().insertChar(ch);
086:                getRMC().insertChar(ch);
087:            }
088:
089:            /** <P>Updates the BraceReduction to reflect cursor movement. Negative values move left from the cursor, 
090:             *  positive values move right. </P>
091:             *  @param count indicates the direction and magnitude of cursor movement
092:             */
093:            public void move(int count) {
094:                try {
095:                    getRMB().move(count);
096:                    getRMC().move(count);
097:                } catch (IllegalArgumentException e) {
098:                    resetLocation();
099:                    throw new UnexpectedException(e);
100:                }
101:            }
102:
103:            /** <P>Update the BraceReduction to reflect text deletion.</P>
104:             *  @param count indicates the size and direction of text deletion. Negative values delete text to the left of the
105:             *  cursor, positive values delete text to the right.
106:             */
107:            public void delete(int count) {
108:                getRMB().delete(count);
109:                getRMC().delete(count);
110:            }
111:
112:            /** <P>Finds the closing brace that matches the next significant brace iff that brace is an open brace.</P>
113:             *  @return the distance until the matching closing brace.  On failure, returns -1.
114:             *  @see #balanceBackward()
115:             */
116:            public int balanceForward() {
117:                return getRMB().balanceForward();
118:            }
119:
120:            /** <P>Finds the open brace that matches the previous significant brace iff that brace is an closing brace.</P>
121:             *  @return the distance until the matching open brace.  On failure, returns -1.
122:             *  @see #balanceForward()
123:             */
124:            public int balanceBackward() {
125:                return getRMB().balanceBackward();
126:            }
127:
128:            /** This function returns the state at the relDistance, where relDistance is relative to the last time it was called.
129:             *  You can reset the last call to the current offset using resetLocation.
130:             */
131:            public ReducedModelState moveWalkerGetState(int relDistance) {
132:                return getRMC().moveWalkerGetState(relDistance);
133:            }
134:
135:            /** This function resets the location of the walker in the comment list to
136:             *  where the current cursor is. This allows the walker to keep walking and
137:             *  using relative distance instead of having to rewalk the same distance
138:             *  every call to stateAtRelLocation. It is an optimization.
139:             */
140:            public void resetLocation() {
141:                getRMC().resetWalkerLocationToCursor();
142:            }
143:
144:            /** Get the token currently pointed at by the cursor. Because the reduced model is split into two reduced sub-models,
145:             * we have to check each sub-model first as each one has unique information.  If we find a non-gap token in either 
146:             * sub-model we want to return that.  Otherwise, we want to return a sort of hybrid Gap of the two, i.e., a Gap where
147:             * there are neither special comment/quote tokens nor parens/squigglies/brackets.
148:             * @return a ReducedToken representative of the unified reduced model
149:             */
150:            public ReducedToken currentToken() {
151:                // check the reduced comment model for specials
152:                ReducedToken rmcToken = getRMC().current();
153:                if (!rmcToken.isGap())
154:                    return rmcToken;
155:                // check the reduced brace model for braces
156:                ReducedToken rmbToken = getRMB().current();
157:                if (!rmbToken.isGap()) {
158:                    rmbToken.setState(getRMC().getStateAtCurrent());
159:                    return rmbToken;
160:                }
161:                // otherwise, we have a gap.
162:                int size = getSize(rmbToken, rmcToken);
163:                return new Gap(size, getRMC().getStateAtCurrent());
164:            }
165:
166:            /** Get the shadowing state at the current caret position.
167:             * @return FREE|INSIDE_LINE_COMMENT|INSIDE_BLOCK_COMMENT|
168:             * INSIDE_SINGLE_QUOTE|INSIDE_DOUBLE_QUOTE
169:             */
170:            public ReducedModelState getStateAtCurrent() {
171:                return getRMC().getStateAtCurrent();
172:            }
173:
174:            /**
175:             * Get a string representation of the current token's type.
176:             * @return "" if current is a Gap, otherwise, use ReducedToken.getType()
177:             */
178:            String getType() {
179:                ReducedToken rmcToken = getRMC().current();
180:                if (!rmcToken.isGap())
181:                    return rmcToken.getType();
182:
183:                ReducedToken rmbToken = getRMB().current();
184:                if (!rmbToken.isGap()) {
185:                    return rmbToken.getType();
186:                }
187:                return ""; //a gap
188:            }
189:
190:            /**
191:             * Gets the size of the current token.
192:             * It checks both the brace and comment sub-models to find the size
193:             * of the current token.  If the current token is a Gap, we have to reconcile
194:             * the information of both sub-models in order to get the correct size
195:             * of the current token as seen by the outside world.
196:             * @return the number of characters represented by the current token
197:             */
198:            int getSize() {
199:                return getSize(getRMB().current(), getRMC().current());
200:            }
201:
202:            int getSize(ReducedToken rmbToken, ReducedToken rmcToken) {
203:                int rmb_offset = getRMB().getBlockOffset();
204:                int rmc_offset = getRMC().getBlockOffset();
205:                int rmb_size = rmbToken.getSize();
206:                int rmc_size = rmcToken.getSize();
207:                int size;
208:                if (rmb_offset < rmc_offset) {
209:                    size = rmb_offset;
210:                    _offset = size;
211:                } else {
212:                    size = rmc_offset;
213:                    _offset = size;
214:                }
215:
216:                if (rmb_size - rmb_offset < rmc_size - rmc_offset) {
217:                    size += (rmb_size - rmb_offset);
218:                } else {
219:                    size += (rmc_size - rmc_offset);
220:                }
221:                return size;
222:            }
223:
224:            /**
225:             * Move the reduced model to the next token and update the cursor information.
226:             */
227:            void next() {
228:                if (getRMC()._cursor.atStart()) {
229:                    getRMC().next();
230:                    getRMB().next();
231:                    return;
232:                }
233:                int size = getSize(getRMB().current(), getRMC().current());
234:                getRMC().move(size - _offset);
235:                getRMB().move(size - _offset);
236:            }
237:
238:            /**
239:             * Move the reduced model to the previous token and update the cursor information.
240:             */
241:            void prev() {
242:                int size;
243:                if (getRMC()._cursor.atEnd()) {
244:                    getRMC().prev();
245:                    getRMB().prev();
246:                    if (getRMC()._cursor.atStart()) {
247:                        return; // because in place now.
248:                    }
249:
250:                    if (getRMC().current().getSize() < getRMB().current()
251:                            .getSize()) {
252:                        size = -getRMC().current().getSize();
253:                    } else {
254:                        size = -getRMB().current().getSize();
255:                    }
256:                    getRMC().next();
257:                    getRMB().next();
258:                    move(size);
259:                } else if (getRMB().getBlockOffset() < getRMC()
260:                        .getBlockOffset()) {
261:                    getRMB().prev();
262:                    size = getRMB().current().getSize()
263:                            + getRMB().getBlockOffset();
264:                    getRMB().next();
265:                    if (size < getRMC().getBlockOffset()) {
266:                        move(-size);
267:                    } else {
268:                        move(-getRMC().getBlockOffset());
269:                    }
270:                } else if (getRMB().getBlockOffset() == getRMC()
271:                        .getBlockOffset()) {
272:                    getRMB().prev();
273:                    getRMC().prev();
274:                    getRMB().setBlockOffset(0);
275:                    getRMC().setBlockOffset(0);
276:                } else {
277:                    getRMC().prev();
278:                    size = getRMC().current().getSize()
279:                            + getRMC().getBlockOffset();
280:                    getRMC().next();
281:                    if (size < getRMB().getBlockOffset()) {
282:                        move(-size);
283:                    } else {
284:                        move(-getRMB().getBlockOffset());
285:                    }
286:                }
287:            }
288:
289:            /**
290:             * Get the previous token.
291:             */
292:            public ReducedToken prevItem() {
293:                int rmbOffset = getRMB().getBlockOffset();
294:                int rmcOffset = getRMC().getBlockOffset();
295:
296:                prev();
297:                ReducedToken temp = currentToken();
298:                next();
299:
300:                getRMB().setBlockOffset(rmbOffset);
301:                getRMC().setBlockOffset(rmcOffset);
302:                return temp;
303:            }
304:
305:            /**
306:             * Get the next token.
307:             */
308:            public ReducedToken nextItem() {
309:                int rmbOffset = getRMB().getBlockOffset();
310:                int rmcOffset = getRMC().getBlockOffset();
311:                next();
312:                ReducedToken temp = currentToken();
313:                prev();
314:                getRMB().setBlockOffset(rmbOffset);
315:                getRMC().setBlockOffset(rmcOffset);
316:                return temp;
317:            }
318:
319:            /** Determines if the cursor is at the end of the reduced model. */
320:            boolean atEnd() {
321:                return (getRMB()._cursor.atEnd() || getRMC()._cursor.atEnd());
322:            }
323:
324:            /** Determines if the cursor is at the start of the reduced model. */
325:            boolean atStart() {
326:                return (getRMB()._cursor.atStart() || getRMC()._cursor
327:                        .atStart());
328:            }
329:
330:            /** Gets the offset within the current token. */
331:            int getBlockOffset() {
332:                if (getRMB().getBlockOffset() < getRMC().getBlockOffset())
333:                    return getRMB().getBlockOffset();
334:                return getRMC().getBlockOffset();
335:            }
336:
337:            /** Gets the absolute character offset into the document represented by the reduced model. */
338:            public int absOffset() {
339:                return getRMC().absOffset();
340:            }
341:
342:            /** A toString() substitute. */
343:            public String simpleString() {
344:                return "\n********\n" + getRMB().simpleString()
345:                        + "\n________\n" + getRMC().simpleString();
346:            }
347:
348:            /** Returns an IndentInfo containing the following information:
349:             * - distance to the previous newline ( start of this line)
350:             * - distance to the brace enclosing the beginning of the current line
351:             * - distance to the beginning of the line containing that brace
352:             */
353:            public IndentInfo getIndentInformation() {
354:                IndentInfo braceInfo = new IndentInfo();
355:                //get distance to the previous newline (in braceInfo.distToNewline)
356:                getRMC().getDistToPreviousNewline(braceInfo);
357:                //get distance to the closing brace before that new line.
358:                getRMB().getDistToEnclosingBrace(braceInfo);
359:                //get distance to newline before the previous, just mentioned, brace.
360:                getRMC().getDistToIndentNewline(braceInfo);
361:                // get distance to the brace enclosing the current location
362:                getRMB().getDistToEnclosingBraceCurrent(braceInfo);
363:                // get distance to the beginning of that brace's line
364:                getRMC().getDistToCurrentBraceNewline(braceInfo);
365:                return braceInfo;
366:            }
367:
368:            /** Gets distance to end of line on the line previous. */
369:            public int getDistToPreviousNewline(int relLoc) {
370:                return getRMC().getDistToPreviousNewline(relLoc);
371:            }
372:
373:            public int getDistToNextNewline() {
374:                return getRMC().getDistToNextNewline();
375:            }
376:
377:            /** Return all highlight status info for text between the current location and current location + length.  This should
378:             * collapse adjoining blocks with the same status into one.
379:             * @param start The start location of the area for which we want the status.  The reduced model is already at this
380:             *    position, but this value is needed to determine the absolute positions in HighlightStatus objects we return.
381:             * @param length The length of the text segment for which status information must be generated.
382:             */
383:            public Vector<HighlightStatus> getHighlightStatus(final int start,
384:                    final int length) {
385:                Vector<HighlightStatus> vec = new Vector<HighlightStatus>();
386:
387:                int curState;
388:                int curLocation;
389:                int curLength;
390:
391:                TokenList.Iterator cursor = getRMC()._cursor._copy();
392:                //    int ct = rmc._tokens.listenerCount();
393:                curLocation = start;
394:                // NOTE: old code threw an exception if cursor.atStart(); it used wrong value for curLength atEnd too
395:                //    curLength = ! cursor.atEnd() ? cursor.current().getSize() - rmc.getBlockOffset() : start + length; 
396:                //    curState = ! cursor.atEnd() ? cursor.current().getHighlightState() : 0;
397:                if (cursor.atEnd() || cursor.atStart()) { // cursor is not inside a reduced model token
398:                    curLength = length;
399:                    curState = 0;
400:                } else {
401:                    curLength = cursor.current().getSize()
402:                            - getRMC().getBlockOffset();
403:                    curState = cursor.current().getHighlightState();
404:                }
405:
406:                while ((curLocation + curLength) < (start + length)) {
407:                    cursor.next();
408:                    //TODO: figure out why this function is iterating past the end of the collection
409:                    //when it gets called from the ColoringGlyphPainter after deleting the last character
410:                    if (cursor.atEnd())
411:                        break;
412:                    int nextState = cursor.current().getHighlightState();
413:
414:                    if (nextState == curState) {
415:                        // add on and keep building
416:                        curLength += cursor.current().getSize();
417:                    } else {
418:                        // add old one to the vector and start new one
419:                        vec.add(new HighlightStatus(curLocation, curLength,
420:                                curState));
421:                        curLocation += curLength; // new block starts after previous one
422:                        curLength = cursor.current().getSize();
423:                        curState = nextState;
424:                    }
425:                }
426:
427:                // Make sure this token length doesn't extend past start+length.
428:                // This is because we guarantee that the returned vector only refers
429:                // to chars on [start, start+length).
430:                int requestEnd = start + length;
431:                if ((curLocation + curLength) > requestEnd) {
432:                    curLength = requestEnd - curLocation;
433:                }
434:
435:                // Add the last one, which has not been added yet
436:                vec.add(new HighlightStatus(curLocation, curLength, curState));
437:
438:                cursor.dispose();
439:
440:                return vec;
441:            }
442:        }
w___ww___.ja_v__a___2__s___.c_o_m___ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.