Source Code Cross Referenced for SystemBuffer.java in  » IDE » J » org » armedbear » j » 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
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » J » org.armedbear.j 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * SystemBuffer.java
003:         *
004:         * Copyright (C) 1998-2003 Peter Graves
005:         * $Id: SystemBuffer.java,v 1.15 2003/06/14 17:49:03 piso Exp $
006:         *
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License
009:         * as published by the Free Software Foundation; either version 2
010:         * of the License, or (at your option) any later version.
011:         *
012:         * This program is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015:         * GNU General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU General Public License
018:         * along with this program; if not, write to the Free Software
019:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020:         */
021:
022:        package org.armedbear.j;
023:
024:        import java.io.BufferedOutputStream;
025:        import java.io.IOException;
026:        import java.io.InputStream;
027:        import java.io.UnsupportedEncodingException;
028:        import java.util.List;
029:
030:        // System buffers are NOT linked into the normal buffer ring.
031:        public class SystemBuffer implements  Constants {
032:            public static final int TYPE_SYSTEM = 0;
033:            public static final int TYPE_NORMAL = 1;
034:            public static final int TYPE_ARCHIVE = 2;
035:            public static final int TYPE_DIRECTORY = 3;
036:            public static final int TYPE_SHELL = 4;
037:            public static final int TYPE_MAN = 5;
038:            public static final int TYPE_OUTPUT = 6;
039:            public static final int TYPE_IMAGE = 7;
040:            public static final int TYPE_MAILBOX = 8;
041:            public static final int TYPE_TELNET = 9;
042:            public static final int TYPE_SSH = 10;
043:            public static final int TYPE_LIST_OCCURRENCES = 11;
044:
045:            protected int type = TYPE_SYSTEM;
046:            protected boolean readOnly;
047:            protected boolean forceReadOnly;
048:            protected Mode mode;
049:            protected String lineSeparator;
050:            protected int lineCount;
051:
052:            private boolean isLoaded;
053:            private Line firstLine;
054:            private Line lastLine;
055:            private File file;
056:            private String loadEncoding;
057:            private List tags;
058:
059:            public SystemBuffer() {
060:            }
061:
062:            public SystemBuffer(File file) {
063:                this .file = file;
064:            }
065:
066:            public final int getType() {
067:                return type;
068:            }
069:
070:            public final synchronized Line getFirstLine() {
071:                return firstLine;
072:            }
073:
074:            public synchronized void setFirstLine(Line line) {
075:                firstLine = line;
076:            }
077:
078:            public final Position getEnd() {
079:                Line line = firstLine;
080:                if (line == null)
081:                    return null;
082:                while (line.next() != null)
083:                    line = line.next();
084:                return new Position(line, line.length());
085:            }
086:
087:            public final File getFile() {
088:                return file;
089:            }
090:
091:            public final void setFile(File file) {
092:                this .file = file;
093:            }
094:
095:            public final synchronized boolean isLoaded() {
096:                return isLoaded;
097:            }
098:
099:            public final synchronized void setLoaded(boolean b) {
100:                isLoaded = b;
101:            }
102:
103:            public final Mode getMode() {
104:                return mode;
105:            }
106:
107:            public final int getModeId() {
108:                return mode == null ? 0 : mode.getId();
109:            }
110:
111:            public final String getModeName() {
112:                return mode == null ? null : mode.toString();
113:            }
114:
115:            public synchronized final List getTags() {
116:                return tags;
117:            }
118:
119:            public synchronized final void setTags(List tags) {
120:                this .tags = tags;
121:            }
122:
123:            public final void setForceReadOnly(boolean b) {
124:                forceReadOnly = b;
125:            }
126:
127:            public String getLineSeparator() {
128:                return lineSeparator;
129:            }
130:
131:            public final boolean contains(Line line) {
132:                Line l = getFirstLine();
133:                while (l != null) {
134:                    if (l == line)
135:                        return true;
136:                    l = l.next();
137:                }
138:                return false;
139:            }
140:
141:            public int load() {
142:                if (!isLoaded) {
143:                    try {
144:                        if (file.isFile()) {
145:                            InputStream in = file.getInputStream();
146:                            if (in != null) {
147:                                load(in, file.getEncoding());
148:                                in.close();
149:                            }
150:                        }
151:                        if (getFirstLine() == null) {
152:                            // New or 0-byte file.
153:                            appendLine("");
154:                            lineSeparator = System
155:                                    .getProperty("line.separator");
156:                        }
157:                    } catch (IOException e) {
158:                        Log.error(e);
159:                    }
160:                    isLoaded = true;
161:                }
162:                return LOAD_COMPLETED;
163:            }
164:
165:            public void load(InputStream istream, String encoding) {
166:                if (mode != null && mode.getId() == BINARY_MODE) {
167:                    loadBinary(istream);
168:                    return;
169:                }
170:                byte[] buf = new byte[4096];
171:                int totalBytes = 0;
172:                try {
173:                    int bytesRead = istream.read(buf);
174:                    loadProgress(totalBytes = totalBytes + bytesRead);
175:                    // Detect Unicode.
176:                    boolean isUnicode = false;
177:                    boolean isLittleEndian = true;
178:                    if (bytesRead >= 2) {
179:                        byte byte1 = buf[0];
180:                        byte byte2 = buf[1];
181:                        if (byte1 == (byte) 0xfe && byte2 == (byte) 0xff) {
182:                            isUnicode = true;
183:                            isLittleEndian = false;
184:                            loadEncoding = "UnicodeBig";
185:                        } else if (byte1 == (byte) 0xff && byte2 == (byte) 0xfe) {
186:                            isUnicode = true;
187:                            loadEncoding = "UnicodeLittle";
188:                        }
189:                    }
190:                    boolean skipLF = false;
191:                    if (isUnicode) {
192:                        FastStringBuffer sb = new FastStringBuffer(256);
193:                        int i = 2;
194:                        while (bytesRead > 0) {
195:                            while (i < bytesRead - 1) {
196:                                char c;
197:                                final byte b1 = buf[i++];
198:                                final byte b2 = buf[i++];
199:                                if (isLittleEndian)
200:                                    c = (char) ((b2 << 8) + (b1 & 0xff));
201:                                else
202:                                    c = (char) ((b1 << 8) + (b2 & 0xff));
203:                                switch (c) {
204:                                case '\r':
205:                                    appendLine(sb.toString());
206:                                    sb.setLength(0);
207:                                    skipLF = true;
208:                                    break;
209:                                case '\n':
210:                                    if (skipLF) {
211:                                        // LF after CR.
212:                                        if (lineSeparator == null)
213:                                            lineSeparator = "\r\n";
214:                                        skipLF = false;
215:                                    } else {
216:                                        // LF without preceding CR.
217:                                        if (lineSeparator == null)
218:                                            lineSeparator = "\n";
219:                                        appendLine(sb.toString());
220:                                        sb.setLength(0);
221:                                    }
222:                                    break;
223:                                default:
224:                                    // Normal char.
225:                                    if (skipLF) {
226:                                        // Something other than LF after CR.  Must be a Mac...
227:                                        if (lineSeparator == null)
228:                                            lineSeparator = "\r";
229:                                        skipLF = false;
230:                                    }
231:                                    sb.append(c);
232:                                    break;
233:                                }
234:                            }
235:                            bytesRead = istream.read(buf);
236:                            i = 0;
237:                        }
238:                        if (sb.length() > 0) {
239:                            // No line separator at end of file.
240:                            appendLine(sb.toString());
241:                        } else {
242:                            // If there is a line separator at the end of the file, we
243:                            // need to append an empty line so the line separator will
244:                            // get written out when the file is saved.
245:                            appendLine("");
246:                        }
247:                    } else {
248:                        // Not Unicode.
249:                        if (encoding == null) {
250:                            encoding = Editor.preferences().getStringProperty(
251:                                    Property.DEFAULT_ENCODING);
252:                        }
253:                        loadEncoding = encoding;
254:                        ByteBuffer bb = new ByteBuffer(256);
255:                        while (bytesRead > 0) {
256:                            for (int i = 0; i < bytesRead; i++) {
257:                                byte b = buf[i];
258:                                switch (b) {
259:                                case 13:
260:                                    appendLine(new String(bb.getBytes(), 0, bb
261:                                            .length(), encoding));
262:                                    bb.setLength(0);
263:                                    skipLF = true;
264:                                    break;
265:                                case 10:
266:                                    if (skipLF) {
267:                                        // LF after CR.
268:                                        if (lineSeparator == null)
269:                                            lineSeparator = "\r\n";
270:                                        skipLF = false;
271:                                    } else {
272:                                        // LF without preceding CR.
273:                                        if (lineSeparator == null)
274:                                            lineSeparator = "\n";
275:                                        appendLine(new String(bb.getBytes(), 0,
276:                                                bb.length(), encoding));
277:                                        bb.setLength(0);
278:                                    }
279:                                    break;
280:                                default:
281:                                    // Normal char.
282:                                    if (skipLF) {
283:                                        // Something other than LF after CR.  Must be a Mac...
284:                                        if (lineSeparator == null)
285:                                            lineSeparator = "\r";
286:                                        skipLF = false;
287:                                    }
288:                                    bb.append(b);
289:                                    break;
290:                                }
291:                            }
292:                            bytesRead = istream.read(buf);
293:                            if (bytesRead > 0)
294:                                loadProgress(totalBytes = totalBytes
295:                                        + bytesRead);
296:                        }
297:                        if (bb.length() > 0) {
298:                            // No line separator at end of file.
299:                            appendLine(new String(bb.getBytes(), 0,
300:                                    bb.length(), encoding));
301:                        } else {
302:                            // If there is a line separator at the end of the file, we
303:                            // need to append an empty line so the line separator will
304:                            // get written out when the file is saved.
305:                            appendLine("");
306:                        }
307:                    }
308:                    isLoaded = true;
309:                } catch (Exception e) {
310:                    Log.error(e);
311:                }
312:                loadFinished(isLoaded);
313:            }
314:
315:            public final Line getLastLine() {
316:                return lastLine;
317:            }
318:
319:            public final void setLastLine(Line line) {
320:                lastLine = line;
321:            }
322:
323:            protected void appendLine(Line line) {
324:                line.setPrevious(lastLine);
325:                if (lastLine != null)
326:                    lastLine.setNext(line);
327:                lastLine = line;
328:                if (getFirstLine() == null)
329:                    setFirstLine(line);
330:            }
331:
332:            public void appendLine(String s) {
333:                appendLine(new TextLine(s));
334:            }
335:
336:            public void append(String s) {
337:                int begin = 0;
338:                int end = 0;
339:                boolean skipLF = false;
340:                final int limit = s.length();
341:                for (int i = 0; i < limit; i++) {
342:                    switch (s.charAt(i)) {
343:                    case '\r':
344:                        appendLine(s.substring(begin, end));
345:                        ++end;
346:                        begin = end;
347:                        skipLF = true;
348:                        break;
349:                    case '\n':
350:                        if (skipLF) {
351:                            ++begin;
352:                            ++end;
353:                            skipLF = false;
354:                        } else {
355:                            appendLine(s.substring(begin, end));
356:                            ++end;
357:                            begin = end;
358:                        }
359:                        break;
360:                    default:
361:                        skipLF = false;
362:                        ++end;
363:                    }
364:                }
365:                if (begin < end)
366:                    appendLine(s.substring(begin, end));
367:            }
368:
369:            private void appendBinaryLine(int start, byte[] bytes, int numBytes) {
370:                appendLine(new BinaryLine(start, bytes, numBytes));
371:            }
372:
373:            // Overridden by Buffer.renumber().
374:            public void renumber() {
375:                for (Line line = getFirstLine(); line != null; line = line
376:                        .next())
377:                    line.setLineNumber(lineCount++);
378:            }
379:
380:            public void writeBuffer() throws SaveException {
381:                if (file.isFile() && !file.canWrite()) {
382:                    Log.error("writeFile: file is not writable: " + file);
383:                    throw new SaveException(file, file.canonicalPath()
384:                            + " is not writable");
385:                }
386:                if (Platform.isPlatformWindows()) {
387:                    // writeTemporaryFile() throws a SaveException if an error occurs.
388:                    File tempFile = writeTemporaryFile();
389:                    if (!makePatchFile()) {
390:                        if (!Utilities.makeBackup(file, false)) {
391:                            Log.error("backup failed");
392:                            throw new SaveException(file,
393:                                    "Unable to write backup file for "
394:                                            + file.canonicalPath());
395:                        }
396:                    }
397:                    if (!Utilities.deleteRename(tempFile, file)) {
398:                        Log.error("unable to rename "
399:                                + tempFile.canonicalPath() + " to "
400:                                + file.canonicalPath());
401:                        throw new SaveException(file,
402:                                "Unable to rename temporary file");
403:                    }
404:                } else {
405:                    // Save in place on Unix to preserve permissions and ownership of
406:                    // file. Keep original (instead of renaming it) when making backup.
407:                    if (!makePatchFile()) {
408:                        if (!Utilities.makeBackup(file, true)) {
409:                            Log.error("backup failed");
410:                            throw new SaveException(file,
411:                                    "Unable to write backup file for "
412:                                            .concat(file.canonicalPath()));
413:                        }
414:                    }
415:                    // Write directly to original file.
416:                    if (!writeFile(file)) {
417:                        Log.error("writeFile failed");
418:                        throw new SaveException(file, "Unable to write "
419:                                .concat(file.canonicalPath()));
420:                    }
421:                }
422:            }
423:
424:            // Returns true if patch file was created successfully.
425:            private final boolean makePatchFile() {
426:                if (file.isFile()) {
427:                    File patchFile = getPatchFile();
428:                    if (patchFile != null) {
429:                        if (!patchFile.isFile())
430:                            return Utilities.copyFile(file, patchFile);
431:                    }
432:                }
433:                return false;
434:            }
435:
436:            // Returns null if "patchmode" preference is not set.
437:            // Public for DiffMode.diff().
438:            public final File getPatchFile() {
439:                String suffix;
440:                if (this  instanceof  Buffer)
441:                    suffix = ((Buffer) this )
442:                            .getStringProperty(Property.PATCH_MODE);
443:                else if (mode != null)
444:                    suffix = mode.getStringProperty(Property.PATCH_MODE);
445:                else {
446:                    suffix = Editor.preferences().getStringProperty(
447:                            Property.PATCH_MODE);
448:                }
449:                if (suffix != null) {
450:                    suffix = suffix.trim();
451:                    if (suffix.length() > 0) {
452:                        if (suffix.charAt(0) != '.')
453:                            suffix = ".".concat(suffix);
454:                        return File.getInstance(file.canonicalPath().concat(
455:                                suffix));
456:                    }
457:                }
458:                return null;
459:            }
460:
461:            public boolean writeFile(File outputFile) {
462:                try {
463:                    BufferedOutputStream out = new BufferedOutputStream(
464:                            outputFile.getOutputStream());
465:                    if (lineSeparator == null)
466:                        lineSeparator = System.getProperty("line.separator");
467:                    String encoding = outputFile.getEncoding();
468:                    if (encoding == null)
469:                        encoding = getSaveEncoding();
470:                    Line line = getFirstLine();
471:                    if (line != null) {
472:                        final byte[] byteOrderMark = getByteOrderMark(encoding);
473:                        if (byteOrderMark != null)
474:                            out.write(byteOrderMark);
475:                        out.write(line.getBytes(encoding));
476:                        line = line.next();
477:                        final byte[] sepBytes = getSeparatorBytes(encoding);
478:                        while (line != null) {
479:                            out.write(sepBytes);
480:                            out.write(line.getBytes(encoding));
481:                            line = line.next();
482:                        }
483:                    }
484:                    out.flush();
485:                    out.close();
486:                    return true;
487:                } catch (IOException e) {
488:                    Log.error(e);
489:                    return false;
490:                }
491:            }
492:
493:            public String getSaveEncoding() {
494:                String encoding = file == null ? null : file.getEncoding();
495:                if (encoding == null) {
496:                    encoding = loadEncoding;
497:                    if (encoding == null)
498:                        encoding = Editor.preferences().getStringProperty(
499:                                Property.DEFAULT_ENCODING);
500:                }
501:                if (encoding == null)
502:                    Debug.bug();
503:                return encoding;
504:            }
505:
506:            byte[] getByteOrderMark(String encoding)
507:                    throws UnsupportedEncodingException {
508:                byte[] bytes = "test".getBytes(encoding);
509:                if ((bytes[0] == (byte) 0xfe && bytes[1] == (byte) 0xff)
510:                        || (bytes[0] == (byte) 0xff && bytes[1] == (byte) 0xfe)) {
511:                    byte[] byteOrderMark = new byte[2];
512:                    byteOrderMark[0] = bytes[0];
513:                    byteOrderMark[1] = bytes[1];
514:                    return byteOrderMark;
515:                }
516:                return null;
517:            }
518:
519:            byte[] getSeparatorBytes(String encoding)
520:                    throws UnsupportedEncodingException {
521:                byte[] bytes = lineSeparator.getBytes(encoding);
522:                if (bytes.length > 2) {
523:                    if ((bytes[0] == (byte) 0xfe && bytes[1] == (byte) 0xff)
524:                            || (bytes[0] == (byte) 0xff && bytes[1] == (byte) 0xfe)) {
525:                        byte[] sepBytes = new byte[bytes.length - 2];
526:                        for (int i = 0; i < sepBytes.length; i++)
527:                            sepBytes[i] = bytes[i + 2];
528:                        return sepBytes;
529:                    }
530:                }
531:                return bytes;
532:            }
533:
534:            /*package*/synchronized void _empty() {
535:                Line line = getFirstLine();
536:                while (line != null) {
537:                    Line nextLine = line.next();
538:                    line.setPrevious(null);
539:                    line.setNext(null);
540:                    line = nextLine;
541:                }
542:                setFirstLine(null);
543:                lastLine = null;
544:                isLoaded = false;
545:            }
546:
547:            protected void loadProgress(int totalBytesRead) {
548:                // Default behavior is to do nothing.
549:            }
550:
551:            protected void loadFinished(boolean success) {
552:                // Default behavior is to do nothing.
553:            }
554:
555:            private void loadBinary(InputStream istream) {
556:                byte[] array = readAllBytes(istream);
557:                if (array != null) {
558:                    for (int start = 0; start < array.length; start += 16) {
559:                        int bytesLeft = array.length - start;
560:                        int count = bytesLeft >= 16 ? 16 : bytesLeft;
561:                        appendBinaryLine(start, array, count);
562:                    }
563:                    isLoaded = true;
564:                }
565:                loadFinished(isLoaded);
566:            }
567:
568:            private byte[] readAllBytes(InputStream in) {
569:                final int chunkSize = 0x8000;
570:                byte[] array = null;
571:                int totalBytes = 0;
572:                byte[] chunk = new byte[chunkSize];
573:                int bytesRead;
574:                try {
575:                    while ((bytesRead = in.read(chunk, 0, chunk.length)) > 0) {
576:                        if (array == null) {
577:                            array = new byte[bytesRead];
578:                            System.arraycopy(chunk, 0, array, 0, bytesRead);
579:                        } else {
580:                            // Allocate new array big enough to hold all the bytes.
581:                            byte[] newArray = new byte[totalBytes + bytesRead];
582:
583:                            // Copy old array into new array.
584:                            if (totalBytes > 0)
585:                                System.arraycopy(array, 0, newArray, 0,
586:                                        totalBytes);
587:
588:                            // Append current chunk.
589:                            System.arraycopy(chunk, 0, newArray, totalBytes,
590:                                    bytesRead);
591:
592:                            array = newArray;
593:                        }
594:                        totalBytes += bytesRead;
595:                        Debug.assertTrue(array.length == totalBytes);
596:                    }
597:                } catch (IOException e) {
598:                    Log.error(e);
599:                    array = null;
600:                }
601:                return array;
602:            }
603:
604:            private File writeTemporaryFile() throws SaveException {
605:                boolean succeeded = false;
606:                // First try to write out a temporary file in the current directory.
607:                File tempFile = Utilities.getTempFile(file.getParent());
608:                if (tempFile != null)
609:                    succeeded = writeFile(tempFile);
610:                if (!succeeded) {
611:                    // We were not able to write out the temporary file in the current
612:                    // directory, possibly because the current directory is not
613:                    // writable. Try again using j's temp directory.
614:                    tempFile = Utilities.getTempFile();
615:                    if (tempFile != null)
616:                        succeeded = writeFile(tempFile);
617:                }
618:                if (!succeeded) {
619:                    throw new SaveException(file,
620:                            "Unable to write temporary file for ".concat(file
621:                                    .canonicalPath()));
622:                }
623:                return tempFile;
624:            }
625:        }
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.