001: package net.sourceforge.squirrel_sql.client.session.mainpanel.objecttree.tabs;
002:
003: /*
004: * Copyright (C) 2007 Rob Manning
005: * manningr@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library 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 GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: import java.awt.BorderLayout;
022: import java.sql.PreparedStatement;
023: import java.sql.ResultSet;
024:
025: import javax.swing.JTextArea;
026:
027: import net.sourceforge.squirrel_sql.client.session.ISession;
028: import net.sourceforge.squirrel_sql.fw.codereformat.CodeReformator;
029: import net.sourceforge.squirrel_sql.fw.codereformat.CommentSpec;
030: import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities;
031: import net.sourceforge.squirrel_sql.fw.util.StringManager;
032: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
033: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
034: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
035:
036: /**
037: * This will provide source code formatting for object source to subclasses.
038: * The subclass only needs to call setupFormatter if code reformatting is
039: * desired and whether or not to compressWhitespace, which is on by default.
040: * Without calling setupFormatter, word-wrapping on word boundaries is still
041: * performed and whitespace is compressed, if so configured.
042: *
043: * @author manningr
044: */
045: public abstract class FormattedSourceTab extends BaseSourceTab {
046:
047: /** Logger for this class. */
048: private final static ILogger s_log = LoggerController
049: .createLogger(FormattedSourceTab.class);
050:
051: private static final StringManager s_stringMgr = StringManagerFactory
052: .getStringManager(FormattedSourceTab.class);
053:
054: /** does the work of formatting */
055: private CodeReformator formatter = null;
056:
057: /** whether or not to compress whitespace */
058: private boolean compressWhitespace = true;
059:
060: private CommentSpec[] commentSpecs = new CommentSpec[] {
061: new CommentSpec("/*", "*/"), new CommentSpec("--", "\n") };
062:
063: /** The String to use to separate statements */
064: protected String statementSeparator = null;
065:
066: /** Whether or not to appendSeparator before reformatting */
067: protected boolean appendSeparator = true;
068:
069: static interface i18n {
070: //i18n[FormatterSourceTab.noSourceAvailable=No object source code is
071: //available]
072: String NO_SOURCE_AVAILABLE = s_stringMgr
073: .getString("FormatterSourceTab.noSourceAvailable");
074: }
075:
076: public FormattedSourceTab(String hint) {
077: super (hint);
078: super .setSourcePanel(new FormattedSourcePanel());
079: }
080:
081: /**
082: * Sets up the formatter which formats the source after retrieving it from
083: * the ResultSet. If this is not setup prior to loading, then the formatter
084: * will not be used - only whitespace compressed if so enabled.
085: *
086: * @param stmtSep
087: * the formatter needs to know what the statement separator is.
088: * @param commentSpecs
089: * the types of comments that can be found in the source code.
090: * This can be null, and if so, the standard comment styles are
091: * used (i.e. -- and c-style comments)
092: */
093: protected void setupFormatter(String stmtSep,
094: CommentSpec[] commentSpecs) {
095: if (commentSpecs != null) {
096: this .commentSpecs = commentSpecs;
097: }
098: statementSeparator = stmtSep;
099: formatter = new CodeReformator(stmtSep, this .commentSpecs);
100: }
101:
102: /**
103: * Whether or not to convert multiple consecutive spaces into a single
104: * space.
105: *
106: * @param compressWhitespace
107: */
108: protected void setCompressWhitespace(boolean compressWhitespace) {
109: this .compressWhitespace = compressWhitespace;
110: }
111:
112: /**
113: * The panel that displays the formatted source code.
114: */
115: private final class FormattedSourcePanel extends BaseSourcePanel {
116: private static final long serialVersionUID = 1L;
117:
118: private JTextArea _ta;
119:
120: FormattedSourcePanel() {
121: super (new BorderLayout());
122: _ta = new JTextArea();
123: _ta.setEditable(false);
124: add(_ta, BorderLayout.CENTER);
125: }
126:
127: public void load(ISession session, PreparedStatement stmt) {
128: _ta.setText("");
129:
130: // always wrap on word boundaries
131: _ta.setWrapStyleWord(true);
132:
133: ResultSet rs = null;
134: try {
135: rs = stmt.executeQuery();
136: StringBuffer buf = new StringBuffer(4096);
137: while (rs.next()) {
138: String line = rs.getString(1);
139: if (line == null) {
140: s_log
141: .debug("load: Null object source line; skipping...");
142: continue;
143: }
144: if (compressWhitespace) {
145: buf.append(line.trim() + " ");
146: } else {
147: buf.append(line);
148: }
149: }
150: if (appendSeparator) {
151: buf.append("\n");
152: buf.append(statementSeparator);
153: }
154: if (formatter != null && buf.length() != 0) {
155: if (s_log.isDebugEnabled()) {
156: s_log
157: .debug("Object source code before formatting: "
158: + buf.toString());
159: }
160: _ta.setText(format(buf.toString()));
161: } else {
162: if (buf.length() == 0) {
163: buf.append(i18n.NO_SOURCE_AVAILABLE);
164: }
165: _ta.setText(buf.toString());
166: }
167: _ta.setCaretPosition(0);
168:
169: } catch (Exception ex) {
170: if (s_log.isDebugEnabled()) {
171: s_log.debug(
172: "Unexpected exception while formatting "
173: + "object source code", ex);
174: }
175: session.showErrorMessage(ex);
176: } finally {
177: SQLUtilities.closeResultSet(rs);
178: }
179: }
180: }
181:
182: /**
183: * We trap any IllegalStateException from the formatter here. If the SQL
184: * source code fails to format, log it and show the original unformatted
185: * version.
186: *
187: * @param toFormat the SQL to format.
188: *
189: * @return either formatted or original version of the specified SQL.
190: */
191: private String format(String toFormat) {
192: String result = toFormat;
193: try {
194: result = formatter.reformat(toFormat);
195: } catch (IllegalStateException e) {
196: s_log.error("format: Formatting SQL failed: "
197: + e.getMessage(), e);
198: }
199: return result;
200: }
201: }
|