001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.derby;
017:
018: import org.apache.geronimo.gbean.GBeanInfo;
019: import org.apache.geronimo.gbean.GBeanInfoBuilder;
020:
021: import java.io.File;
022: import java.io.RandomAccessFile;
023: import java.nio.CharBuffer;
024: import java.nio.MappedByteBuffer;
025: import java.nio.channels.FileChannel;
026: import java.nio.charset.Charset;
027: import java.util.LinkedList;
028: import java.util.List;
029: import java.util.regex.Matcher;
030: import java.util.regex.Pattern;
031: import java.util.regex.PatternSyntaxException;
032:
033: /**
034: * ReplaceMe
035: *
036: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
037: */
038: public class DerbyLogGBean implements DerbyLog {
039: // Pattern that matches a single line (used to calculate line numbers and text search in a line)
040: private final static Pattern FULL_LINE_PATTERN = Pattern.compile(
041: "^.*", Pattern.MULTILINE);
042: private final DerbySystem derby;
043: private File logFile = null;
044:
045: public DerbyLogGBean(DerbySystem derby) {
046: this .derby = derby;
047: }
048:
049: public SearchResults searchLog(Integer startLine, Integer endLine,
050: Integer max, String text) {
051: // Get log file
052: if (logFile == null) {
053: logFile = new File(derby.getDerbyHome(), "derby.log");
054: if (!logFile.canRead()) {
055: throw new IllegalStateException(
056: "Cannot read Derby log file at '"
057: + logFile.getAbsolutePath() + "'");
058: }
059: }
060: // Check that the text pattern is valid
061: Pattern textPattern;
062: try {
063: textPattern = text == null || text.equals("") ? null
064: : Pattern.compile(text);
065: } catch (PatternSyntaxException e) {
066: throw new IllegalArgumentException(
067: "Bad regular expression '" + text + "'");
068: }
069: return searchFile(logFile, textPattern, startLine, endLine,
070: max == null ? MAX_SEARCH_RESULTS : Math.min(
071: MAX_SEARCH_RESULTS, max.intValue()));
072: }
073:
074: private static SearchResults searchFile(File file,
075: Pattern textSearch, Integer start, Integer stop, int max) {
076: List list = new LinkedList();
077: boolean capped = false;
078: int lineCount = 0;
079: try {
080: RandomAccessFile raf = new RandomAccessFile(file, "r");
081: FileChannel fc = raf.getChannel();
082: MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY,
083: 0, fc.size());
084: CharBuffer cb = Charset.forName("US-ASCII").decode(bb); //todo: does Derby use a different charset on a foreign PC?
085: Matcher lines = FULL_LINE_PATTERN.matcher(cb);
086: Matcher text = textSearch == null ? null : textSearch
087: .matcher("");
088: max = Math.min(max, MAX_SEARCH_RESULTS);
089: while (lines.find()) {
090: ++lineCount;
091: if (start != null && start.intValue() > lineCount) {
092: continue;
093: }
094: if (stop != null && stop.intValue() < lineCount) {
095: continue;
096: }
097: CharSequence line = cb.subSequence(lines.start(), lines
098: .end());
099: if (text != null) {
100: text.reset(line);
101: if (!text.find()) {
102: continue;
103: }
104: }
105: list.add(new LogMessage(lineCount, line.toString()));
106: if (list.size() > max) {
107: list.remove(0);
108: capped = true;
109: }
110: }
111: fc.close();
112: raf.close();
113: } catch (Exception e) {
114: }
115: return new SearchResults(lineCount, (LogMessage[]) list
116: .toArray(new LogMessage[list.size()]), capped);
117: }
118:
119: public static final GBeanInfo GBEAN_INFO;
120:
121: static {
122: GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(
123: "Derby Log", DerbyLogGBean.class);
124:
125: infoFactory.addReference("DerbySystem", DerbySystem.class,
126: "GBean");
127: infoFactory.addInterface(DerbyLog.class);
128: infoFactory.setConstructor(new String[] { "DerbySystem" });
129:
130: GBEAN_INFO = infoFactory.getBeanInfo();
131: }
132:
133: public static GBeanInfo getGBeanInfo() {
134: return GBEAN_INFO;
135: }
136: }
|