1 /*******************************************************************************
2 * Copyright (c) 2000, 2003 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.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;
26 import net.sourceforge.phpdt.core.compiler.CharOperation;
27 import net.sourceforge.phpdt.internal.core.util.PHPFileUtil;
31 public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
33 public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
35 // public final static char[] SUFFIX_class = ".class".toCharArray();
37 // public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray();
39 public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$
41 public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$
42 // public final static char[] SUFFIX_jar = ".jar".toCharArray();
44 // public final static char[] SUFFIX_JAR = ".JAR".toCharArray();
47 public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$
49 public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$
51 private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
53 private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
55 private static final int DEFAULT_READING_SIZE = 8192;
57 /* Bundle containing messages */
58 protected static ResourceBundle bundle;
60 private final static String bundleName = "net.sourceforge.phpdt.internal.compiler.util.messages"; //$NON-NLS-1$
66 * Lookup the message with the given ID in this catalog and bind its
67 * substitution locations with the given strings.
69 public static String bind(String id, String binding1, String binding2) {
70 return bind(id, new String[] { binding1, binding2 });
74 * Lookup the message with the given ID in this catalog and bind its
75 * substitution locations with the given string.
77 public static String bind(String id, String binding) {
78 return bind(id, new String[] { binding });
82 * Lookup the message with the given ID in this catalog and bind its
83 * substitution locations with the given string values.
85 public static String bind(String id, String[] bindings) {
87 return "No message available"; //$NON-NLS-1$
88 String message = null;
90 message = bundle.getString(id);
91 } catch (MissingResourceException e) {
92 // If we got an exception looking for the message, fail gracefully
94 // the id we were looking for. In most cases this is
95 // semi-informative so is not too bad.
96 return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
98 // for compatibility with MessageFormat which eliminates double quotes
99 // in original message
100 char[] messageWithNoDoubleQuotes = CharOperation.replace(message
101 .toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
102 message = new String(messageWithNoDoubleQuotes);
104 if (bindings == null)
107 int length = message.length();
110 StringBuffer output = new StringBuffer(80);
112 if ((end = message.indexOf('{', start)) > -1) {
113 output.append(message.substring(start + 1, end));
114 if ((start = message.indexOf('}', end)) > -1) {
117 index = Integer.parseInt(message.substring(end + 1,
119 output.append(bindings[index]);
120 } catch (NumberFormatException nfe) {
121 output.append(message.substring(end + 1, start + 1));
122 } catch (ArrayIndexOutOfBoundsException e) {
124 .append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
127 output.append(message.substring(end, length));
131 output.append(message.substring(start + 1, length));
135 return output.toString();
139 * Lookup the message with the given ID in this catalog
141 public static String bind(String id) {
142 return bind(id, (String[]) null);
146 * Creates a NLS catalog for the given locale.
148 public static void relocalize() {
150 bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
151 } catch (MissingResourceException e) {
153 .println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
159 * Returns the given bytes as a char array using a given encoding (null
160 * means platform default).
162 public static char[] bytesToChar(byte[] bytes, String encoding)
165 return getInputStreamAsCharArray(new ByteArrayInputStream(bytes),
166 bytes.length, encoding);
171 * Returns the contents of the given file as a byte array.
173 * @throws IOException
174 * if a problem occured reading the file.
176 public static byte[] getFileByteContent(File file) throws IOException {
177 InputStream stream = null;
179 stream = new BufferedInputStream(new FileInputStream(file));
180 return getInputStreamAsByteArray(stream, (int) file.length());
182 if (stream != null) {
185 } catch (IOException e) {
192 * Returns the contents of the given file as a char array. When encoding is
193 * null, then the platform default one is used
195 * @throws IOException
196 * if a problem occured reading the file.
198 public static char[] getFileCharContent(File file, String encoding)
200 InputStream stream = null;
202 stream = new BufferedInputStream(new FileInputStream(file));
203 return Util.getInputStreamAsCharArray(stream, (int) file.length(),
206 if (stream != null) {
209 } catch (IOException e) {
216 * Returns the given input stream's contents as a byte array. If a length is
217 * specified (ie. if length != -1), only length bytes are returned.
218 * Otherwise all bytes in the stream are returned. Note this doesn't close
221 * @throws IOException
222 * if a problem occured reading the stream.
224 public static byte[] getInputStreamAsByteArray(InputStream stream,
225 int length) throws IOException {
228 contents = new byte[0];
229 int contentsLength = 0;
232 int amountRequested = Math.max(stream.available(),
233 DEFAULT_READING_SIZE); // read at least 8K
235 // resize contents if needed
236 if (contentsLength + amountRequested > contents.length) {
237 System.arraycopy(contents, 0,
238 contents = new byte[contentsLength
239 + amountRequested], 0, contentsLength);
242 // read as many bytes as possible
243 amountRead = stream.read(contents, contentsLength,
246 if (amountRead > 0) {
247 // remember length of contents
248 contentsLength += amountRead;
250 } while (amountRead != -1);
252 // resize contents if necessary
253 if (contentsLength < contents.length) {
254 System.arraycopy(contents, 0,
255 contents = new byte[contentsLength], 0, contentsLength);
258 contents = new byte[length];
261 while ((readSize != -1) && (len != length)) {
263 // We record first the read size. In this case len is the actual
266 readSize = stream.read(contents, len, length - len);
274 * Returns the given input stream's contents as a character array. If a
275 * length is specified (ie. if length != -1), only length chars are
276 * returned. Otherwise all chars in the stream are returned. Note this
277 * doesn't close the stream.
279 * @throws IOException
280 * if a problem occured reading the stream.
282 public static char[] getInputStreamAsCharArray(InputStream stream,
283 int length, String encoding) throws IOException {
284 InputStreamReader reader = null;
285 reader = encoding == null ? new InputStreamReader(stream)
286 : new InputStreamReader(stream, encoding);
289 contents = CharOperation.NO_CHAR;
290 int contentsLength = 0;
293 int amountRequested = Math.max(stream.available(),
294 DEFAULT_READING_SIZE); // read at least 8K
296 // resize contents if needed
297 if (contentsLength + amountRequested > contents.length) {
298 System.arraycopy(contents, 0,
299 contents = new char[contentsLength
300 + amountRequested], 0, contentsLength);
303 // read as many chars as possible
304 amountRead = reader.read(contents, contentsLength,
307 if (amountRead > 0) {
308 // remember length of contents
309 contentsLength += amountRead;
311 } while (amountRead != -1);
313 // resize contents if necessary
314 if (contentsLength < contents.length) {
315 System.arraycopy(contents, 0,
316 contents = new char[contentsLength], 0, contentsLength);
319 contents = new char[length];
322 while ((readSize != -1) && (len != length)) {
324 // We record first the read size. In this case len is the actual
327 readSize = reader.read(contents, len, length - len);
330 // Now we need to resize in case the default encoding used more than
334 System.arraycopy(contents, 0, (contents = new char[len]), 0,
342 * Returns the contents of the given zip entry as a byte array.
344 * @throws IOException
345 * if a problem occured reading the zip entry.
347 public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip)
350 InputStream stream = null;
352 stream = new BufferedInputStream(zip.getInputStream(ze));
353 return getInputStreamAsByteArray(stream, (int) ze.getSize());
355 if (stream != null) {
358 } catch (IOException e) {
365 * Returns true iff str.toLowerCase().endsWith(".jar") ||
366 * str.toLowerCase().endsWith(".zip") implementation is not creating extra
369 // public final static boolean isArchiveFileName(String name) {
370 // int nameLength = name == null ? 0 : name.length();
371 // int suffixLength = SUFFIX_JAR.length;
372 // if (nameLength < suffixLength) return false;
374 // // try to match as JAR file
375 // for (int i = 0; i < suffixLength; i++) {
376 // char c = name.charAt(nameLength - i - 1);
377 // int suffixIndex = suffixLength - i - 1;
378 // if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) {
380 // // try to match as ZIP file
381 // suffixLength = SUFFIX_ZIP.length;
382 // if (nameLength < suffixLength) return false;
383 // for (int j = 0; j < suffixLength; j++) {
384 // c = name.charAt(nameLength - j - 1);
385 // suffixIndex = suffixLength - j - 1;
386 // if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return
395 * Returns true iff str.toLowerCase().endsWith(".class") implementation is
396 * not creating extra strings.
398 // public final static boolean isClassFileName(String name) {
399 // int nameLength = name == null ? 0 : name.length();
400 // int suffixLength = SUFFIX_CLASS.length;
401 // if (nameLength < suffixLength) return false;
403 // for (int i = 0; i < suffixLength; i++) {
404 // char c = name.charAt(nameLength - i - 1);
405 // int suffixIndex = suffixLength - i - 1;
406 // if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex])
412 * Returns true iff str.toLowerCase().endsWith(".java") implementation is
413 * not creating extra strings.
415 public final static boolean isJavaFileName(String name) {
416 return PHPFileUtil.isPHPFileName(name);
417 // int nameLength = name == null ? 0 : name.length();
418 // int suffixLength = SUFFIX_JAVA.length;
419 // if (nameLength < suffixLength) return false;
421 // for (int i = 0; i < suffixLength; i++) {
422 // char c = name.charAt(nameLength - i - 1);
423 // int suffixIndex = suffixLength - i - 1;
424 // if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex])