X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Futil%2FUtil.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Futil%2FUtil.java;h=94b7567a0f1f080f82a8ac037d8e4876d2d7a4e6;hb=040fa5af2cd00017cf3575950cdaade34a6d7f6c;hp=0000000000000000000000000000000000000000;hpb=a580fb8376d315d05e4d6bfdff9ff1101a151cd6;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/util/Util.java b/src/org/eclipse/jdt/internal/compiler/util/Util.java new file mode 100644 index 0000000..94b7567 --- /dev/null +++ b/src/org/eclipse/jdt/internal/compiler/util/Util.java @@ -0,0 +1,523 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.compiler.util; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.eclipse.jdt.core.compiler.CharOperation; + +public class Util implements SuffixConstants { + + public interface Displayable { + String displayString(Object o); + } + + public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$ + public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray(); + + private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$ + private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$ + private static final int DEFAULT_READING_SIZE = 8192; + + /* Bundle containing messages */ + protected static ResourceBundle bundle; + private final static String bundleName = + "org.eclipse.jdt.internal.compiler.util.messages"; //$NON-NLS-1$ + static { + relocalize(); + } + /** + * Lookup the message with the given ID in this catalog and bind its + * substitution locations with the given strings. + */ + public static String bind(String id, String binding1, String binding2) { + return bind(id, new String[] { binding1, binding2 }); + } + /** + * Lookup the message with the given ID in this catalog and bind its + * substitution locations with the given string. + */ + public static String bind(String id, String binding) { + return bind(id, new String[] { binding }); + } + /** + * Lookup the message with the given ID in this catalog and bind its + * substitution locations with the given string values. + */ + public static String bind(String id, String[] bindings) { + if (id == null) + return "No message available"; //$NON-NLS-1$ + String message = null; + try { + message = bundle.getString(id); + } catch (MissingResourceException e) { + // If we got an exception looking for the message, fail gracefully by just returning + // the id we were looking for. In most cases this is semi-informative so is not too bad. + return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$ + } + // for compatibility with MessageFormat which eliminates double quotes in original message + char[] messageWithNoDoubleQuotes = + CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE); + + if (bindings == null) return new String(messageWithNoDoubleQuotes); + + int length = messageWithNoDoubleQuotes.length; + int start = 0; + int end = length; + StringBuffer output = null; + while (true) { + if ((end = CharOperation.indexOf('{', messageWithNoDoubleQuotes, start)) > -1) { + if (output == null) output = new StringBuffer(length+bindings.length*20); + output.append(messageWithNoDoubleQuotes, start, end - start); + if ((start = CharOperation.indexOf('}', messageWithNoDoubleQuotes, end + 1)) > -1) { + int index = -1; + String argId = new String(messageWithNoDoubleQuotes, end + 1, start - end - 1); + try { + index = Integer.parseInt(argId); + output.append(bindings[index]); + } catch (NumberFormatException nfe) { // could be nested message ID {compiler.name} + boolean done = false; + if (!id.equals(argId)) { + String argMessage = null; + try { + argMessage = bundle.getString(argId); + output.append(argMessage); + done = true; + } catch (MissingResourceException e) { + // unable to bind argument, ignore (will leave argument in) + } + } + if (!done) output.append(messageWithNoDoubleQuotes, end + 1, start - end); + } catch (ArrayIndexOutOfBoundsException e) { + output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$ + } + start++; + } else { + output.append(messageWithNoDoubleQuotes, end, length); + break; + } + } else { + if (output == null) return new String(messageWithNoDoubleQuotes); + output.append(messageWithNoDoubleQuotes, start, length - start); + break; + } + } + return output.toString(); + } + /** + * Lookup the message with the given ID in this catalog + */ + public static String bind(String id) { + return bind(id, (String[]) null); + } + /** + * Creates a NLS catalog for the given locale. + */ + public static void relocalize() { + try { + bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault()); + } catch(MissingResourceException e) { + System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$ + throw e; + } + } + /** + * Returns the given bytes as a char array using a given encoding (null means platform default). + */ + public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException { + + return getInputStreamAsCharArray(new ByteArrayInputStream(bytes), bytes.length, encoding); + + } + /** + * Returns the contents of the given file as a byte array. + * @throws IOException if a problem occured reading the file. + */ + public static byte[] getFileByteContent(File file) throws IOException { + InputStream stream = null; + try { + stream = new BufferedInputStream(new FileInputStream(file)); + return getInputStreamAsByteArray(stream, (int) file.length()); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + } + } + /** + * Returns the contents of the given file as a char array. + * When encoding is null, then the platform default one is used + * @throws IOException if a problem occured reading the file. + */ + public static char[] getFileCharContent(File file, String encoding) throws IOException { + InputStream stream = null; + try { + stream = new BufferedInputStream(new FileInputStream(file)); + return getInputStreamAsCharArray(stream, (int) file.length(), encoding); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + } + } + /* + * NIO support to get input stream as byte array. + * Not used as with JDK 1.4.2 this support is slower than standard IO one... + * Keep it as comment for future in case of next JDK versions improve performance + * in this area... + * + public static byte[] getInputStreamAsByteArray(FileInputStream stream, int length) + throws IOException { + + FileChannel channel = stream.getChannel(); + int size = (int)channel.size(); + if (length >= 0 && length < size) size = length; + byte[] contents = new byte[size]; + ByteBuffer buffer = ByteBuffer.wrap(contents); + channel.read(buffer); + return contents; + } + */ + /** + * Returns the given input stream's contents as a byte array. + * If a length is specified (ie. if length != -1), only length bytes + * are returned. Otherwise all bytes in the stream are returned. + * Note this doesn't close the stream. + * @throws IOException if a problem occured reading the stream. + */ + public static byte[] getInputStreamAsByteArray(InputStream stream, int length) + throws IOException { + byte[] contents; + if (length == -1) { + contents = new byte[0]; + int contentsLength = 0; + int amountRead = -1; + do { + int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K + + // resize contents if needed + if (contentsLength + amountRequested > contents.length) { + System.arraycopy( + contents, + 0, + contents = new byte[contentsLength + amountRequested], + 0, + contentsLength); + } + + // read as many bytes as possible + amountRead = stream.read(contents, contentsLength, amountRequested); + + if (amountRead > 0) { + // remember length of contents + contentsLength += amountRead; + } + } while (amountRead != -1); + + // resize contents if necessary + if (contentsLength < contents.length) { + System.arraycopy( + contents, + 0, + contents = new byte[contentsLength], + 0, + contentsLength); + } + } else { + contents = new byte[length]; + int len = 0; + int readSize = 0; + while ((readSize != -1) && (len != length)) { + // See PR 1FMS89U + // We record first the read size. In this case len is the actual read size. + len += readSize; + readSize = stream.read(contents, len, length - len); + } + } + + return contents; + } + /* + * NIO support to get input stream as char array. + * Not used as with JDK 1.4.2 this support is slower than standard IO one... + * Keep it as comment for future in case of next JDK versions improve performance + * in this area... + public static char[] getInputStreamAsCharArray(FileInputStream stream, int length, String encoding) + throws IOException { + + FileChannel channel = stream.getChannel(); + int size = (int)channel.size(); + if (length >= 0 && length < size) size = length; + Charset charset = encoding==null?systemCharset:Charset.forName(encoding); + if (charset != null) { + MappedByteBuffer bbuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size); + CharsetDecoder decoder = charset.newDecoder(); + CharBuffer buffer = decoder.decode(bbuffer); + char[] contents = new char[buffer.limit()]; + buffer.get(contents); + return contents; + } + throw new UnsupportedCharsetException(SYSTEM_FILE_ENCODING); + } + */ + /** + * Returns the given input stream's contents as a character array. + * If a length is specified (ie. if length != -1), only length chars + * are returned. Otherwise all chars in the stream are returned. + * Note this doesn't close the stream. + * @throws IOException if a problem occured reading the stream. + */ + public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) + throws IOException { + InputStreamReader reader = null; + reader = encoding == null + ? new InputStreamReader(stream) + : new InputStreamReader(stream, encoding); + char[] contents; + if (length == -1) { + contents = CharOperation.NO_CHAR; + int contentsLength = 0; + int amountRead = -1; + do { + int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K + + // resize contents if needed + if (contentsLength + amountRequested > contents.length) { + System.arraycopy( + contents, + 0, + contents = new char[contentsLength + amountRequested], + 0, + contentsLength); + } + + // read as many chars as possible + amountRead = reader.read(contents, contentsLength, amountRequested); + + if (amountRead > 0) { + // remember length of contents + contentsLength += amountRead; + } + } while (amountRead != -1); + + // Do not keep first character for UTF-8 BOM encoding + int start = 0; + if (contentsLength > 0 && "UTF-8".equals(encoding)) { //$NON-NLS-1$ + if (contents[0] == 0xFEFF) { // if BOM char then skip + contentsLength--; + start = 1; + } + } + // resize contents if necessary + if (contentsLength < contents.length) { + System.arraycopy( + contents, + start, + contents = new char[contentsLength], + 0, + contentsLength); + } + } else { + contents = new char[length]; + int len = 0; + int readSize = 0; + while ((readSize != -1) && (len != length)) { + // See PR 1FMS89U + // We record first the read size. In this case len is the actual read size. + len += readSize; + readSize = reader.read(contents, len, length - len); + } + // Do not keep first character for UTF-8 BOM encoding + int start = 0; + if (length > 0 && "UTF-8".equals(encoding)) { //$NON-NLS-1$ + if (contents[0] == 0xFEFF) { // if BOM char then skip + len--; + start = 1; + } + } + // See PR 1FMS89U + // Now we need to resize in case the default encoding used more than one byte for each + // character + if (len != length) + System.arraycopy(contents, start, (contents = new char[len]), 0, len); + } + + return contents; + } + + /** + * Returns the contents of the given zip entry as a byte array. + * @throws IOException if a problem occured reading the zip entry. + */ + public static byte[] getZipEntryByteContent(ZipEntry ze, ZipFile zip) + throws IOException { + + InputStream stream = null; + try { + stream = new BufferedInputStream(zip.getInputStream(ze)); + return getInputStreamAsByteArray(stream, (int) ze.getSize()); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + } + } + /** + * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip") + * implementation is not creating extra strings. + */ + public final static boolean isArchiveFileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_JAR.length; + if (nameLength < suffixLength) return false; + + // try to match as JAR file + for (int i = 0; i < suffixLength; i++) { + char c = name.charAt(nameLength - i - 1); + int suffixIndex = suffixLength - i - 1; + if (c != SUFFIX_jar[suffixIndex] && c != SUFFIX_JAR[suffixIndex]) { + + // try to match as ZIP file + suffixLength = SUFFIX_ZIP.length; + if (nameLength < suffixLength) return false; + for (int j = 0; j < suffixLength; j++) { + c = name.charAt(nameLength - j - 1); + suffixIndex = suffixLength - j - 1; + if (c != SUFFIX_zip[suffixIndex] && c != SUFFIX_ZIP[suffixIndex]) return false; + } + return true; + } + } + return true; + } + /** + * Returns true iff str.toLowerCase().endsWith(".class") + * implementation is not creating extra strings. + */ + public final static boolean isClassFileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_CLASS.length; + if (nameLength < suffixLength) return false; + + for (int i = 0; i < suffixLength; i++) { + char c = name.charAt(nameLength - i - 1); + int suffixIndex = suffixLength - i - 1; + if (c != SUFFIX_class[suffixIndex] && c != SUFFIX_CLASS[suffixIndex]) return false; + } + return true; + } + /** + * Returns true iff str.toLowerCase().endsWith(".class") + * implementation is not creating extra strings. + */ + public final static boolean isClassFileName(char[] name) { + int nameLength = name == null ? 0 : name.length; + int suffixLength = SUFFIX_CLASS.length; + if (nameLength < suffixLength) return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name[offset + i]; + if (c != SUFFIX_class[i] && c != SUFFIX_CLASS[i]) return false; + } + return true; + } + /** + * Returns true iff str.toLowerCase().endsWith(".java") + * implementation is not creating extra strings. + */ + public final static boolean isJavaFileName(String name) { + int nameLength = name == null ? 0 : name.length(); + int suffixLength = SUFFIX_JAVA.length; + if (nameLength < suffixLength) return false; + + for (int i = 0; i < suffixLength; i++) { + char c = name.charAt(nameLength - i - 1); + int suffixIndex = suffixLength - i - 1; + if (c != SUFFIX_java[suffixIndex] && c != SUFFIX_JAVA[suffixIndex]) return false; + } + return true; + } + /** + * Returns true iff str.toLowerCase().endsWith(".java") + * implementation is not creating extra strings. + */ + public final static boolean isJavaFileName(char[] name) { + int nameLength = name == null ? 0 : name.length; + int suffixLength = SUFFIX_JAVA.length; + if (nameLength < suffixLength) return false; + + for (int i = 0, offset = nameLength - suffixLength; i < suffixLength; i++) { + char c = name[offset + i]; + if (c != SUFFIX_java[i] && c != SUFFIX_JAVA[i]) return false; + } + return true; + } + /** + * Converts an array of Objects into String. + */ + public static String toString(Object[] objects) { + return toString(objects, + new Displayable(){ + public String displayString(Object o) { + if (o == null) return "null"; //$NON-NLS-1$ + return o.toString(); + } + }); + } + + /** + * Converts an array of Objects into String. + */ + public static String toString(Object[] objects, Displayable renderer) { + if (objects == null) return ""; //$NON-NLS-1$ + StringBuffer buffer = new StringBuffer(10); + for (int i = 0; i < objects.length; i++){ + if (i > 0) buffer.append(", "); //$NON-NLS-1$ + buffer.append(renderer.displayString(objects[i])); + } + return buffer.toString(); + } + + /** + * Converts a boolean value into Boolean. + * @param bool The boolean to convert + * @return The corresponding Boolean object (TRUE or FALSE). + */ + public static Boolean toBoolean(boolean bool) { + if (bool) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } +}