1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.util;
13 import java.io.BufferedInputStream;
14 import java.io.ByteArrayInputStream;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.io.InputStreamReader;
20 import java.util.Locale;
21 import java.util.MissingResourceException;
22 import java.util.ResourceBundle;
23 import java.util.zip.ZipEntry;
24 import java.util.zip.ZipFile;
28 public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
29 public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
30 public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$
31 public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$
32 public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$
33 public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$
34 public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$
35 public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$
36 public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$
37 public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$
39 private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
40 private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
42 /* Bundle containing messages */
43 protected static ResourceBundle bundle;
44 private final static String bundleName =
45 "org.eclipse.jdt.internal.compiler.util.messages"; //$NON-NLS-1$
50 * Lookup the message with the given ID in this catalog and bind its
51 * substitution locations with the given strings.
53 public static String bind(String id, String binding1, String binding2) {
54 return bind(id, new String[] { binding1, binding2 });
57 * Lookup the message with the given ID in this catalog and bind its
58 * substitution locations with the given string.
60 public static String bind(String id, String binding) {
61 return bind(id, new String[] { binding });
64 * Lookup the message with the given ID in this catalog and bind its
65 * substitution locations with the given string values.
67 public static String bind(String id, String[] bindings) {
69 return "No message available"; //$NON-NLS-1$
70 String message = null;
72 message = bundle.getString(id);
73 } catch (MissingResourceException e) {
74 // If we got an exception looking for the message, fail gracefully by just returning
75 // the id we were looking for. In most cases this is semi-informative so is not too bad.
76 return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
78 // for compatibility with MessageFormat which eliminates double quotes in original message
79 char[] messageWithNoDoubleQuotes =
80 CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
81 message = new String(messageWithNoDoubleQuotes);
86 int length = message.length();
89 StringBuffer output = new StringBuffer(80);
91 if ((end = message.indexOf('{', start)) > -1) {
92 output.append(message.substring(start + 1, end));
93 if ((start = message.indexOf('}', end)) > -1) {
96 index = Integer.parseInt(message.substring(end + 1, start));
97 output.append(bindings[index]);
98 } catch (NumberFormatException nfe) {
99 output.append(message.substring(end + 1, start + 1));
100 } catch (ArrayIndexOutOfBoundsException e) {
101 output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
104 output.append(message.substring(end, length));
108 output.append(message.substring(start + 1, length));
112 return output.toString();
115 * Lookup the message with the given ID in this catalog
117 public static String bind(String id) {
118 return bind(id, (String[]) null);
121 * Creates a NLS catalog for the given locale.
123 public static void relocalize() {
124 bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
127 * Returns the given bytes as a char array using a given encoding (null means platform default).
129 public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException {
131 return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.length, encoding);
135 * Returns the contents of the given file as a byte array.
136 * @throws IOException if a problem occured reading the file.
138 public static byte[] getFileByteContent(File file) throws IOException {
139 InputStream stream = null;
141 stream = new BufferedInputStream(new FileInputStream(file));
142 return getInputStreamAsByteArray(stream, (int) file.length());
144 if (stream != null) {
147 } catch (IOException e) {
153 * Returns the contents of the given file as a char array.
154 * When encoding is null, then the platform default one is used
155 * @throws IOException if a problem occured reading the file.
157 public static char[] getFileCharContent(File file, String encoding) throws IOException {
158 InputStream stream = null;
160 stream = new BufferedInputStream(new FileInputStream(file));
161 return Util.getInputStreamAsCharArray(stream, (int) file.length(), encoding);
163 if (stream != null) {
166 } catch (IOException e) {
172 * Returns the given input stream's contents as a byte array.
173 * If a length is specified (ie. if length != -1), only length bytes
174 * are returned. Otherwise all bytes in the stream are returned.
175 * Note this doesn't close the stream.
176 * @throws IOException if a problem occured reading the stream.
178 public static byte[] getInputStreamAsByteArray(InputStream stream, int length)
182 contents = new byte[0];
183 int contentsLength = 0;
186 int available = stream.available();
188 // resize contents if needed
189 if (contentsLength + available > contents.length) {
193 contents = new byte[contentsLength + available],
198 // read as many bytes as possible
199 bytesRead = stream.read(contents, contentsLength, available);
202 // remember length of contents
203 contentsLength += bytesRead;
205 } while (bytesRead > 0);
207 // resize contents if necessary
208 if (contentsLength < contents.length) {
212 contents = new byte[contentsLength],
217 contents = new byte[length];
220 while ((readSize != -1) && (len != length)) {
222 // We record first the read size. In this case len is the actual read size.
224 readSize = stream.read(contents, len, length - len);
231 * Returns the given input stream's contents as a character array.
232 * If a length is specified (ie. if length != -1), only length chars
233 * are returned. Otherwise all chars in the stream are returned.
234 * Note this doesn't close the stream.
235 * @throws IOException if a problem occured reading the stream.
237 public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding)
239 InputStreamReader reader = null;
240 reader = encoding == null
241 ? new InputStreamReader(stream)
242 : new InputStreamReader(stream, encoding);
245 contents = new char[0];
246 int contentsLength = 0;
249 int available = stream.available();
251 // resize contents if needed
252 if (contentsLength + available > contents.length) {
256 contents = new char[contentsLength + available],
261 // read as many chars as possible
262 charsRead = reader.read(contents, contentsLength, available);
265 // remember length of contents
266 contentsLength += charsRead;
268 } while (charsRead > 0);
270 // resize contents if necessary
271 if (contentsLength < contents.length) {
275 contents = new char[contentsLength],
280 contents = new char[length];
283 while ((readSize != -1) && (len != length)) {
285 // We record first the read size. In this case len is the actual read size.
287 readSize = reader.read(contents, len, length - len);
290 // Now we need to resize in case the default encoding used more than one byte for each
293 System.arraycopy(contents, 0, (contents = new char[len]), 0, len);
300 * Returns the contents of the given zip entry as a byte array.
301 * @throws IOException if a problem occured reading the zip entry.
303 public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip)
306 InputStream stream = null;
308 stream = new BufferedInputStream(zip.getInputStream(ze));
309 return getInputStreamAsByteArray(stream, (int) ze.getSize());
311 if (stream != null) {
314 } catch (IOException e) {
320 * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip")
321 * implementation is not creating extra strings.
323 public final static boolean isArchiveFileName(String name) {
324 int nameLength = name == null ? 0 : name.length();
325 int suffixLength = SUFFIX_JAR.length;
326 if (nameLength < suffixLength) return false;
328 // try to match as JAR file
329 for (int i = 0; i < suffixLength; i++) {
330 char c = name.charAt(nameLength - i - 1);
331 int suffixIndex = suffixLength - i - 1;
332 if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) {
334 // try to match as ZIP file
335 suffixLength = SUFFIX_ZIP.length;
336 if (nameLength < suffixLength) return false;
337 for (int j = 0; j < suffixLength; j++) {
338 c = name.charAt(nameLength - j - 1);
339 suffixIndex = suffixLength - j - 1;
340 if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return false;
348 * Returns true iff str.toLowerCase().endsWith(".class")
349 * implementation is not creating extra strings.
351 public final static boolean isClassFileName(String name) {
352 int nameLength = name == null ? 0 : name.length();
353 int suffixLength = SUFFIX_CLASS.length;
354 if (nameLength < suffixLength) return false;
356 for (int i = 0; i < suffixLength; i++) {
357 char c = name.charAt(nameLength - i - 1);
358 int suffixIndex = suffixLength - i - 1;
359 if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex]) return false;
364 * Returns true iff str.toLowerCase().endsWith(".java")
365 * implementation is not creating extra strings.
367 public final static boolean isJavaFileName(String name) {
368 int nameLength = name == null ? 0 : name.length();
369 int suffixLength = SUFFIX_JAVA.length;
370 if (nameLength < suffixLength) return false;
372 for (int i = 0; i < suffixLength; i++) {
373 char c = name.charAt(nameLength - i - 1);
374 int suffixIndex = suffixLength - i - 1;
375 if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;