/* * Copyright 2004,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.bsf.util; import java.beans.Introspector; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.net.MalformedURLException; import java.net.URL; import java.util.StringTokenizer; import java.util.Vector; /** * Deals with strings (probably need to elaborate some more). * * @author Matthew J. Duftler */ public class StringUtils { public static final String lineSeparator = System.getProperty("line.separator", "\n"); public static final String lineSeparatorStr = cleanString(lineSeparator); public static String classNameToVarName(String className) { // Might represent an array. int arrayDim = 0; while (className.endsWith("[]")) { className = className.substring(0, className.length() - 2); arrayDim++; } int iLastPeriod = className.lastIndexOf('.'); String varName = Introspector.decapitalize( iLastPeriod != -1 ? className.substring(iLastPeriod + 1) : className); if (arrayDim > 0) { varName += "_" + arrayDim + "D"; } return getValidIdentifierName(varName); } // Ensure that escape sequences are passed through properly. public static String cleanString(String str) { if (str == null) return null; else { char[] charArray = str.toCharArray(); StringBuffer sBuf = new StringBuffer(); for (int i = 0; i < charArray.length; i++) switch (charArray[i]) { case '\"' : sBuf.append("\\\""); break; case '\\' : sBuf.append("\\\\"); break; case '\n' : sBuf.append("\\n"); break; case '\r' : sBuf.append("\\r"); break; default : sBuf.append(charArray[i]); break; } return sBuf.toString(); } } /** * Get a string consisting of <code>numberOfChars</code> theChars. * * @return a string consisting of <code>numberOfChars</code> theChars. */ public static String getChars(int numberOfChars, char theChar) { if (numberOfChars <= 0) return ""; StringBuffer sRet = new StringBuffer(numberOfChars); for (int i = 0; i < numberOfChars; i++) sRet.append(theChar); return sRet.toString(); } /* This method will return the correct name for a class object representing a primitive, a single instance of a class, as well as n-dimensional arrays of primitives or instances. This logic is needed to handle the string returned from Class.getName(). If the class object represents a single instance (or a primitive), Class.getName() returns the fully-qualified name of the class and no further work is needed. However, if the class object represents an array (of n dimensions), Class.getName() returns a Descriptor (the Descriptor grammar is defined in section 4.3 of the Java VM Spec). This method will parse the Descriptor if necessary. */ public static String getClassName(Class targetClass) { String className = targetClass.getName(); return targetClass.isArray() ? parseDescriptor(className) : className; } public static String getCommaListFromVector(Vector sourceVector) { StringBuffer strBuf = new StringBuffer(); for (int i = 0; i < sourceVector.size(); i++) { strBuf.append((i > 0 ? ", " : "") + sourceVector.elementAt(i)); } return strBuf.toString(); } /* Returns a Reader for reading from the specified resource, if the resource points to a stream. */ public static Reader getContentAsReader(URL url) throws SecurityException, IllegalArgumentException, IOException { if (url == null) { throw new IllegalArgumentException("URL cannot be null."); } try { Object content = url.getContent(); if (content == null) { throw new IllegalArgumentException("No content."); } if (content instanceof InputStream) { Reader in = new InputStreamReader((InputStream)content); if (in.ready()) { return in; } else { throw new FileNotFoundException(); } } else { throw new IllegalArgumentException((content instanceof String) ? (String)content : "This URL points to a: " + StringUtils.getClassName(content.getClass())); } } catch (SecurityException e) { throw new SecurityException("Your JVM's SecurityManager has disallowed this."); } catch (FileNotFoundException e) { throw new FileNotFoundException("This file was not found: " + url); } } /* Shorthand for: IOUtils.getStringFromReader(getContentAsReader(url)). */ public static String getContentAsString(URL url) throws SecurityException, IllegalArgumentException, IOException { return IOUtils.getStringFromReader(getContentAsReader(url)); } // Handles multi-line strings. public static String getSafeString(String scriptStr) { BufferedReader in = new BufferedReader(new StringReader(scriptStr)); StringBuffer strBuf = new StringBuffer(); String tempLine, previousLine = null; try { while ((tempLine = in.readLine()) != null) { if (previousLine != null) { strBuf.append("\"" + previousLine + lineSeparatorStr + "\" +" + lineSeparator); } previousLine = cleanString(tempLine); } } catch (IOException e) { } strBuf.append("\"" + (previousLine != null ? previousLine : "") + "\"" + lineSeparator); return strBuf.toString(); } /* */ public static URL getURL(URL contextURL, String spec) throws MalformedURLException { return getURL(contextURL, spec, 1); } /* The recursiveDepth argument is used to insure that the algorithm gives up after hunting 2 levels up in the contextURL's path. */ private static URL getURL(URL contextURL, String spec, int recursiveDepth) throws MalformedURLException { URL url = null; try { url = new URL(contextURL, spec); try { url.openStream(); } catch (IOException ioe1) { throw new MalformedURLException("This file was not found: " + url); } } catch (MalformedURLException e1) { url = new URL("file", "", spec); try { url.openStream(); } catch (IOException ioe2) { if (contextURL != null) { String contextFileName = contextURL.getFile(); String parentName = new File(contextFileName).getParent(); if (parentName != null && recursiveDepth < 3) { return getURL(new URL("file", "", parentName + '/'), spec, recursiveDepth + 1); } } throw new MalformedURLException("This file was not found: " + url); } } return url; } public static String getValidIdentifierName(String identifierName) { if (identifierName == null || identifierName.length() == 0) return null; StringBuffer strBuf = new StringBuffer(); char[] chars = identifierName.toCharArray(); strBuf.append(Character.isJavaIdentifierStart(chars[0]) ? chars[0] : '_' ); for (int i = 1; i < chars.length; i++) { strBuf.append(Character.isJavaIdentifierPart(chars[i]) ? chars[i] : '_' ); } return strBuf.toString(); } public static boolean isValidIdentifierName(String identifierName) { if (identifierName == null || identifierName.length() == 0) return false; char[] chars = identifierName.toCharArray(); if (!Character.isJavaIdentifierStart(chars[0])) return false; for (int i = 1; i < chars.length; i++) if (!Character.isJavaIdentifierPart(chars[i])) return false; return true; } public static boolean isValidPackageName(String packageName) { if (packageName == null) return false; else if (packageName.length() == 0) // Empty is ok. return true; StringTokenizer strTok = new StringTokenizer(packageName, ".", true); // Should have an odd number of tokens (including '.' delimiters). if (strTok.countTokens() % 2 != 1) return false; // Must start with a valid identifier name. if (!isValidIdentifierName(strTok.nextToken())) return false; // ... followed by 0 or more of ".ValidIdentifier". while (strTok.hasMoreTokens()) { // Must be a '.'. if (!strTok.nextToken().equals(".")) return false; // Must be a valid identifier name. if (strTok.hasMoreTokens()) { if (!isValidIdentifierName(strTok.nextToken())) return false; } else return false; } return true; } /* See the comment above for getClassName(targetClass)... */ private static String parseDescriptor(String className) { char[] classNameChars = className.toCharArray(); int arrayDim = 0; int i = 0; while (classNameChars[i] == '[') { arrayDim++; i++; } StringBuffer classNameBuf = new StringBuffer(); switch (classNameChars[i++]) { case 'B' : classNameBuf.append("byte"); break; case 'C' : classNameBuf.append("char"); break; case 'D' : classNameBuf.append("double"); break; case 'F' : classNameBuf.append("float"); break; case 'I' : classNameBuf.append("int"); break; case 'J' : classNameBuf.append("long"); break; case 'S' : classNameBuf.append("short"); break; case 'Z' : classNameBuf.append("boolean"); break; case 'L' : classNameBuf.append(classNameChars, i, classNameChars.length - i - 1); break; } for (i = 0; i < arrayDim; i++) classNameBuf.append("[]"); return classNameBuf.toString(); } }