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.ui.util.PHPFileUtil;
31 public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
32 public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
33 public final static char[] SUFFIX_class = ".class".toCharArray(); //$NON-NLS-1$
34 public final static char[] SUFFIX_CLASS = ".CLASS".toCharArray(); //$NON-NLS-1$
35 public final static char[] SUFFIX_java = ".java".toCharArray(); //$NON-NLS-1$
36 public final static char[] SUFFIX_JAVA = ".JAVA".toCharArray(); //$NON-NLS-1$
37 public final static char[] SUFFIX_jar = ".jar".toCharArray(); //$NON-NLS-1$
38 public final static char[] SUFFIX_JAR = ".JAR".toCharArray(); //$NON-NLS-1$
39 public final static char[] SUFFIX_zip = ".zip".toCharArray(); //$NON-NLS-1$
40 public final static char[] SUFFIX_ZIP = ".ZIP".toCharArray(); //$NON-NLS-1$
42 private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
43 private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
44 private static final int DEFAULT_READING_SIZE = 8192;
46 /* Bundle containing messages */
47 protected static ResourceBundle bundle;
48 private final static String bundleName =
49 "net.sourceforge.phpdt.internal.compiler.util.messages"; //$NON-NLS-1$
54 * Lookup the message with the given ID in this catalog and bind its
55 * substitution locations with the given strings.
57 public static String bind(String id, String binding1, String binding2) {
58 return bind(id, new String[] { binding1, binding2 });
61 * Lookup the message with the given ID in this catalog and bind its
62 * substitution locations with the given string.
64 public static String bind(String id, String binding) {
65 return bind(id, new String[] { binding });
68 * Lookup the message with the given ID in this catalog and bind its
69 * substitution locations with the given string values.
71 public static String bind(String id, String[] bindings) {
73 return "No message available"; //$NON-NLS-1$
74 String message = null;
76 message = bundle.getString(id);
77 } catch (MissingResourceException e) {
78 // If we got an exception looking for the message, fail gracefully by just returning
79 // the id we were looking for. In most cases this is semi-informative so is not too bad.
80 return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
82 // for compatibility with MessageFormat which eliminates double quotes in original message
83 char[] messageWithNoDoubleQuotes =
84 CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
85 message = new String(messageWithNoDoubleQuotes);
90 int length = message.length();
93 StringBuffer output = new StringBuffer(80);
95 if ((end = message.indexOf('{', start)) > -1) {
96 output.append(message.substring(start + 1, end));
97 if ((start = message.indexOf('}', end)) > -1) {
100 index = Integer.parseInt(message.substring(end + 1, start));
101 output.append(bindings[index]);
102 } catch (NumberFormatException nfe) {
103 output.append(message.substring(end + 1, start + 1));
104 } catch (ArrayIndexOutOfBoundsException e) {
105 output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
108 output.append(message.substring(end, length));
112 output.append(message.substring(start + 1, length));
116 return output.toString();
119 * Lookup the message with the given ID in this catalog
121 public static String bind(String id) {
122 return bind(id, (String[]) null);
125 * Creates a NLS catalog for the given locale.
127 public static void relocalize() {
129 bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
130 } catch(MissingResourceException e) {
131 System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
136 * Returns the given bytes as a char array using a given encoding (null means platform default).
138 public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException {
140 return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.length, encoding);
144 * Returns the contents of the given file as a byte array.
145 * @throws IOException if a problem occured reading the file.
147 public static byte[] getFileByteContent(File file) throws IOException {
148 InputStream stream = null;
150 stream = new BufferedInputStream(new FileInputStream(file));
151 return getInputStreamAsByteArray(stream, (int) file.length());
153 if (stream != null) {
156 } catch (IOException e) {
162 * Returns the contents of the given file as a char array.
163 * When encoding is null, then the platform default one is used
164 * @throws IOException if a problem occured reading the file.
166 public static char[] getFileCharContent(File file, String encoding) throws IOException {
167 InputStream stream = null;
169 stream = new BufferedInputStream(new FileInputStream(file));
170 return Util.getInputStreamAsCharArray(stream, (int) file.length(), encoding);
172 if (stream != null) {
175 } catch (IOException e) {
181 * Returns the given input stream's contents as a byte array.
182 * If a length is specified (ie. if length != -1), only length bytes
183 * are returned. Otherwise all bytes in the stream are returned.
184 * Note this doesn't close the stream.
185 * @throws IOException if a problem occured reading the stream.
187 public static byte[] getInputStreamAsByteArray(InputStream stream, int length)
191 contents = new byte[0];
192 int contentsLength = 0;
195 int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K
197 // resize contents if needed
198 if (contentsLength + amountRequested > contents.length) {
202 contents = new byte[contentsLength + amountRequested],
207 // read as many bytes as possible
208 amountRead = stream.read(contents, contentsLength, amountRequested);
210 if (amountRead > 0) {
211 // remember length of contents
212 contentsLength += amountRead;
214 } while (amountRead != -1);
216 // resize contents if necessary
217 if (contentsLength < contents.length) {
221 contents = new byte[contentsLength],
226 contents = new byte[length];
229 while ((readSize != -1) && (len != length)) {
231 // We record first the read size. In this case len is the actual read size.
233 readSize = stream.read(contents, len, length - len);
240 * Returns the given input stream's contents as a character array.
241 * If a length is specified (ie. if length != -1), only length chars
242 * are returned. Otherwise all chars in the stream are returned.
243 * Note this doesn't close the stream.
244 * @throws IOException if a problem occured reading the stream.
246 public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding)
248 InputStreamReader reader = null;
249 reader = encoding == null
250 ? new InputStreamReader(stream)
251 : new InputStreamReader(stream, encoding);
254 contents = CharOperation.NO_CHAR;
255 int contentsLength = 0;
258 int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K
260 // resize contents if needed
261 if (contentsLength + amountRequested > contents.length) {
265 contents = new char[contentsLength + amountRequested],
270 // read as many chars as possible
271 amountRead = reader.read(contents, contentsLength, amountRequested);
273 if (amountRead > 0) {
274 // remember length of contents
275 contentsLength += amountRead;
277 } while (amountRead != -1);
279 // resize contents if necessary
280 if (contentsLength < contents.length) {
284 contents = new char[contentsLength],
289 contents = new char[length];
292 while ((readSize != -1) && (len != length)) {
294 // We record first the read size. In this case len is the actual read size.
296 readSize = reader.read(contents, len, length - len);
299 // Now we need to resize in case the default encoding used more than one byte for each
302 System.arraycopy(contents, 0, (contents = new char[len]), 0, len);
309 * Returns the contents of the given zip entry as a byte array.
310 * @throws IOException if a problem occured reading the zip entry.
312 public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip)
315 InputStream stream = null;
317 stream = new BufferedInputStream(zip.getInputStream(ze));
318 return getInputStreamAsByteArray(stream, (int) ze.getSize());
320 if (stream != null) {
323 } catch (IOException e) {
329 * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip")
330 * implementation is not creating extra strings.
332 public final static boolean isArchiveFileName(String name) {
333 int nameLength = name == null ? 0 : name.length();
334 int suffixLength = SUFFIX_JAR.length;
335 if (nameLength < suffixLength) return false;
337 // try to match as JAR file
338 for (int i = 0; i < suffixLength; i++) {
339 char c = name.charAt(nameLength - i - 1);
340 int suffixIndex = suffixLength - i - 1;
341 if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) {
343 // try to match as ZIP file
344 suffixLength = SUFFIX_ZIP.length;
345 if (nameLength < suffixLength) return false;
346 for (int j = 0; j < suffixLength; j++) {
347 c = name.charAt(nameLength - j - 1);
348 suffixIndex = suffixLength - j - 1;
349 if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return false;
357 * Returns true iff str.toLowerCase().endsWith(".class")
358 * implementation is not creating extra strings.
360 public final static boolean isClassFileName(String name) {
361 int nameLength = name == null ? 0 : name.length();
362 int suffixLength = SUFFIX_CLASS.length;
363 if (nameLength < suffixLength) return false;
365 for (int i = 0; i < suffixLength; i++) {
366 char c = name.charAt(nameLength - i - 1);
367 int suffixIndex = suffixLength - i - 1;
368 if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex]) return false;
373 * Returns true iff str.toLowerCase().endsWith(".java")
374 * implementation is not creating extra strings.
376 public final static boolean isJavaFileName(String name) {
377 return PHPFileUtil.isPHPFileName(name);
378 // int nameLength = name == null ? 0 : name.length();
379 // int suffixLength = SUFFIX_JAVA.length;
380 // if (nameLength < suffixLength) return false;
382 // for (int i = 0; i < suffixLength; i++) {
383 // char c = name.charAt(nameLength - i - 1);
384 // int suffixIndex = suffixLength - i - 1;
385 // if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false;