blob: b6b2ee5820f4bf042c724465f50448ff009852b9 [file] [log] [blame]
/*
* 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();
}
}