001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.util;
024:
025: import java.awt.Toolkit;
026: import java.awt.datatransfer.Clipboard;
027: import java.awt.datatransfer.StringSelection;
028: import java.io.File;
029: import java.io.FileDescriptor;
030: import java.io.FileInputStream;
031: import java.io.FileOutputStream;
032: import java.io.IOException;
033: import java.io.InputStream;
034: import java.io.OutputStream;
035: import java.io.PrintStream;
036: import java.io.Reader;
037: import java.io.Writer;
038: import java.util.Arrays;
039: import java.util.Collection;
040: import java.util.Comparator;
041: import java.util.zip.GZIPOutputStream;
042:
043: import javax.swing.JTable;
044: import javax.xml.parsers.ParserConfigurationException;
045: import javax.xml.parsers.SAXParser;
046: import javax.xml.parsers.SAXParserFactory;
047:
048: import org.xml.sax.SAXException;
049: import org.xml.sax.XMLReader;
050:
051: /**
052: * TODO Add BasicUtilities Overview JavaDoc.
053: * <p>
054: *
055: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
056: * @version 1.0
057: */
058: public class BasicUtilities {
059:
060: private BasicUtilities() {
061:
062: }
063:
064: public static int getCommandMask() {
065:
066: Toolkit toolkit = Toolkit.getDefaultToolkit();
067: return toolkit.getMenuShortcutKeyMask();
068: }
069:
070: /**
071: * Creates a tab delimited text for selected cells of the given JTable.
072: * <p>
073: *
074: * @param table to copy selection from.
075: */
076: public static void copySelectedCellsToClipBoard(JTable table) {
077:
078: if (table != null) {
079: try {
080: table.getCellEditor().cancelCellEditing();
081: } catch (Throwable t) {
082: }
083: StringBuffer buff = new StringBuffer("");
084: StringBuffer row = new StringBuffer("");
085: for (int r = 0; r < table.getRowCount(); r++) {
086: for (int c = 0; c < table.getColumnCount(); c++) {
087: if (table.isCellSelected(r, c))
088: row.append(table.getValueAt(r, c) + "\t");
089: }
090: if (row.toString().trim().length() >= 1) {
091: buff.append(row);
092: buff.append(System.getProperty("line.seperator",
093: "\n"));
094: }
095: row.setLength(0);
096: }
097:
098: Toolkit tk = Toolkit.getDefaultToolkit();
099: Clipboard cb = tk.getSystemClipboard();
100: StringSelection ss = new StringSelection(buff.toString()
101: .trim());
102: cb.setContents(ss, ss);
103: }
104: }
105:
106: /**
107: * Utilitiy method to restore System.out to the default FileDescriptor.
108: * <p>
109: */
110: public static void restoreSystemOut() {
111:
112: PrintStream out = new PrintStream(new FileOutputStream(
113: FileDescriptor.out));
114: System.setOut(out);
115: }
116:
117: /**
118: * Utilitiy method to restore System.err to the default FileDescriptor.
119: * <p>
120: */
121: public static void restoreSystemErr() {
122:
123: PrintStream out = new PrintStream(new FileOutputStream(
124: FileDescriptor.err));
125: System.setErr(out);
126: }
127:
128: /**
129: * Helper method for checking if the current thread is interrupted without resetting the interrupted state.
130: * <p>
131: *
132: * @return <tt>true</tt> if the calling thread is interrupted.
133: */
134: public static boolean isThreadInterrupted() {
135:
136: return Thread.currentThread().isInterrupted();
137: }
138:
139: /**
140: * Creates a generally safe file name.
141: * <p>
142: * This method will hopefully prevent silly errors that can occur by attempting to create a file with illegal
143: * characters. This method more or less takes all the ASCII symbols and converts them to underscores.
144: * <p>
145: * This method more or less is a culmination of what i know to be invalid and or annoying characters to have in a
146: * file name on the systems i know.
147: * <p>
148: * For *NIX users in paticular so extra precautions are made so that the names of these files will be easier to deal
149: * with in shell scripts such that there aren't many characters that will make them difficult when dealing within a
150: * given shell, and shouldn't have to resorting to alot of escape sequences.
151: *
152: * @param fqFilename original filename.
153: * @return String an updated version that should be safe for most systems.
154: */
155: public static String createSafeFilename(final String fileName) {
156:
157: String fqFilename = fileName;
158: fqFilename = fqFilename.replace(File.pathSeparatorChar, '_');
159: fqFilename = fqFilename.replace(File.separatorChar, '_');
160: fqFilename = fqFilename.replace('*', '_');
161: fqFilename = fqFilename.replace(' ', '_');
162: fqFilename = fqFilename.replace('(', '_');
163: fqFilename = fqFilename.replace(')', '_');
164: fqFilename = fqFilename.replace('\'', '_');
165: fqFilename = fqFilename.replace('|', '_');
166: fqFilename = fqFilename.replace('\"', '_');
167: fqFilename = fqFilename.replace(';', '_');
168: fqFilename = fqFilename.replace(':', '_');
169: fqFilename = fqFilename.replace('>', '_');
170: fqFilename = fqFilename.replace('<', '_');
171: fqFilename = fqFilename.replace('[', '_');
172: fqFilename = fqFilename.replace(']', '_');
173: fqFilename = fqFilename.replace('&', '_');
174: fqFilename = fqFilename.replace('#', '_');
175: fqFilename = fqFilename.replace('@', '_');
176: fqFilename = fqFilename.replace('$', '_');
177: fqFilename = fqFilename.replace('%', '_');
178: fqFilename = fqFilename.replace('^', '_');
179: return fqFilename;
180: }
181:
182: /**
183: * Utility method from moving an inputstream to an outputstream.
184: * <p>
185: * Pretty basic stuff here every byte read from in is immediately written to out.
186: *
187: * @param in InputStream to read from.
188: * @param out OutputStream to write to.
189: * @throws IOException if error occurs while write
190: */
191: public static void copyStream(InputStream in, OutputStream out)
192: throws IOException {
193:
194: synchronized (in) {
195: synchronized (out) {
196: byte[] buffer = new byte[256];
197: while (true) {
198: int bytesRead = in.read(buffer);
199: if (bytesRead == -1)
200: break;
201: out.write(buffer, 0, bytesRead);
202: }
203: }
204: }
205: }
206:
207: /**
208: * Utility method from moving an inputstream to an outputstream.
209: * <p>
210: * Pretty basic stuff here every byte read from in is immediately written to out.
211: *
212: * @param in InputStream to read from.
213: * @param out OutputStream to write to.
214: * @throws IOException if error occurs while write
215: */
216: public static void copyReader(Reader in, Writer out)
217: throws IOException {
218:
219: synchronized (in) {
220: synchronized (out) {
221: char[] buffer = new char[256];
222: while (true) {
223: int bytesRead = in.read(buffer);
224: if (bytesRead == -1)
225: break;
226: out.write(buffer, 0, bytesRead);
227: }
228: }
229: }
230: }
231:
232: /**
233: * Helper method for creating an XML reader for parsing XML documents.
234: * <p>
235: *
236: * @param namespaceAware sets namespace aware property in the XMLReader.
237: * @param validating set the validating property with the XMLReader.
238: * @return instance of XMLReader for parsing XML.
239: * @throws ParserConfigurationException if the XMLReader fails to instantiate properly.
240: * @see SAXParserFactory#setNamespaceAware(boolean)
241: * @see SAXParserFactory#setValidating(boolean)
242: */
243: public static XMLReader createXMLReader(boolean namespaceAware,
244: boolean validating) throws ParserConfigurationException {
245:
246: SAXParserFactory spf = SAXParserFactory.newInstance();
247: spf.setNamespaceAware(namespaceAware);
248: spf.setValidating(validating);
249: SAXParser parser = null;
250: try {
251: parser = spf.newSAXParser();
252: return parser.getXMLReader();
253: } catch (SAXException se) {
254: throw new ParserConfigurationException(se.getMessage());
255: }
256: }
257:
258: /**
259: * Utility method for sorting collections.
260: * <p>
261: * This will sort a collection based on the natural ordering of the objects contained in the collection.
262: *
263: * @param collection to be sorted.
264: * @see #sortCollection(Collection, Comparator)
265: */
266: public static void sortCollection(Collection<Object> collection) {
267:
268: sortCollection(collection, null);
269: }
270:
271: /**
272: * Utility method for sorting collections.
273: * <p>
274: * This will sort a collection based on the comparator given. If the given comparator is null then naturall based on
275: * the objects will be used.
276: *
277: * @param collection to be sorted.
278: * @param sorter object that can determine the order of the object in the given collection.
279: * @see #sortCollection(Collection)
280: */
281: public static void sortCollection(Collection<Object> collection,
282: Comparator<Object> sorter) {
283:
284: Object[] array = collection.toArray();
285: collection.clear();
286: if (sorter != null) {
287: Arrays.sort(array, sorter);
288: } else {
289: Arrays.sort(array);
290: }
291: collection.addAll(Arrays.asList(array));
292: }
293:
294: /**
295: * Wraps an exception including the stack trace elements.
296: * <p>
297: *
298: * @param sourceError that needs to be wrapped.
299: * @param wrappedError new error that is a facade of the sourceError.
300: */
301: public static void wrapThrowable(Throwable sourceError,
302: Throwable wrappedError) {
303:
304: if (sourceError == wrappedError
305: || (sourceError == null || wrappedError == null)) {
306: return;
307: }
308:
309: wrappedError.setStackTrace(sourceError.getStackTrace());
310: if (sourceError.getCause() != sourceError) {
311: try {
312: wrappedError.initCause(sourceError.getCause());
313: } catch (IllegalStateException ise) {
314: // cause already set.
315: }
316: }
317: }
318:
319: /**
320: * Backup a specific file to another file using compression.
321: * <p>
322: * This will copy the contents of baseFile to backupFile using a GZIPOutputStream such that it will compressed.
323: *
324: * @param baseFile the file to create a backup of.
325: * @param backupFile the new destination file for the backup.
326: */
327: public static void backupFile(File baseFile, File backupFile)
328: throws IOException {
329:
330: FileInputStream fis = null;
331: FileOutputStream fos = null;
332: try {
333: fis = new FileInputStream(baseFile);
334: fos = new FileOutputStream(backupFile);
335: GZIPOutputStream gzos = new GZIPOutputStream(fos);
336: copyStream(fis, gzos);
337: gzos.finish();
338: gzos.flush();
339: } finally {
340: if (fis != null) {
341: try {
342: fis.close();
343: } catch (Throwable t) {
344: }
345: }
346: if (fos != null) {
347: try {
348: fos.close();
349: } catch (Throwable t) {
350: }
351: }
352: }
353: }
354:
355: /**
356: * Deletes a directory including all childern.
357: * <p>
358: * One small problem that is easily overlooked in Java is that you cannot delete a non-empty directory.
359: * <p>
360: * This method will recursivlely scan the directory for other directories and files and proceed to delete them. This
361: * method should be executed with caution as it provides no safeguards if a directory is accidently deleted.
362: *
363: * @param directory
364: * @return <tt>true</tt> if the directory was successfully deleted.
365: */
366: public static boolean deleteDirectory(File directory) {
367:
368: if (directory.isDirectory()) {
369: String[] children = directory.list();
370: for (int i = 0; i < children.length; i++) {
371: boolean success = deleteDirectory(new File(directory,
372: children[i]));
373: if (!success) {
374: return false;
375: }
376: }
377: }
378: return directory.delete();
379: }
380: }
|