/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 com.sun.jini.tool.envcheck; import com.sun.jini.start.NonActivatableServiceDescriptor; import com.sun.jini.start.SharedActivatableServiceDescriptor; import com.sun.jini.start.SharedActivationGroupDescriptor; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.net.URL; import java.net.URLClassLoader; import java.lang.reflect.Modifier; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; /** * Miscellaneous utility methods for use by the checking framework * and plugins. */ public class Util { /** table of localization resources */ private static final HashMap resourceMap = new HashMap(); /** the resource bundle for this class */ private static ResourceBundle bundle = getResourceBundle(EnvCheck.class); /** the properties which were provided to the local VM */ private static Properties nonStandardProperties = null; /** * Validate the accessibility of the non-directory file identified by * <code>name</code>. The file must exist, must not be a directory, and must * be readable. If any check fails, an error message is returned. If all * checks are successful, <code>null</code> is returned. * * @param name the file name * @param desc a short descriptive string which describes the file, suitable * for inclusion in the error message * @return and error message, or <code>null</code> if all checks pass */ public static String checkFileName(String name, String desc) { File file = new File(name); String canonicalPath = null; try { canonicalPath = file.getCanonicalPath(); } catch (Exception e) { return getString("util.cantresolve", bundle, desc, name); } if (!file.exists()) { return getString("util.notexist", bundle, desc, canonicalPath); } if (file.isDirectory()) { return getString("util.isdir", bundle, desc, canonicalPath); } if (!file.canRead()) { return getString("util.cantread", bundle, desc, canonicalPath); } return null; } /** * Check the accessibility of the given <code>URL</code>. If the * url is a <code>file:</code> url, the usual file access checks are * performed. For any other url a stream is opened, and a non-exceptional * return is considered a success. * * @param url the <code>URL</code> to check * @param desc a description of the source of the url * @return an error message, or <code>null</code> if the access check passes */ public static String checkURL(URL url, String desc) { if ("file".equals(url.getProtocol())) { String path = url.getFile().replace('/', File.separatorChar); return checkFileName(path, desc); } else { try { url.openStream().close(); return null; } catch (IOException e) { return getString("util.cantreadURL", bundle, url.toString(), desc); } } } /** * Validate the accessibility of the non-directory file identified by the * system property <code>prop</code>. The system property must have a * non-<code>null</code> value. The file identified by the value must exist, * must not be a directory, and must be readable. If any check fails, an * error message is returned. If all checks are successful, * <code>null</code> is returned. * * @param prop name of a system property whose value must be a file name * @param desc a short descriptive string which describes the file, suitable * for inclusion in the error message * @return an error message, or <code>null</code> if all checks pass */ public static String checkSystemPropertyFile(String prop, String desc) { String name = System.getProperty(prop); if (name == null) { return getString("util.undef", bundle, desc); } return checkFileName(name, desc); } /** * Get the resource bundle associated with class <code>clazz</code>. The * resource bundle name is constructed by the class name to lower case and * inserting <code>.resources</code> in front of the name. Thus, if * <code>clazz.getName()</code> returned <code>a.b.Foo</code> then the * associated resource bundle name would be <code>a.b.resources.foo</code>. * If no resource bundle having the associated name is found, a stack trace * is printed and <code>null</code> is returned. The resource bundle is * loaded using the class loader for the given class, and is cached so that * the search is performed only once. * * @param clazz the class for which to obtain a resource bundle * @return the resource bundle */ public static ResourceBundle getResourceBundle(Class clazz) { if (resourceMap.containsKey(clazz)) { return (ResourceBundle) resourceMap.get(clazz); } String className = clazz.getName(); int lastDot = className.lastIndexOf("."); if (lastDot < 0) { throw new IllegalStateException("Class is in default package"); } String pkgName = className.substring(0, lastDot); // includes leading '.' String resourceName = className.substring(lastDot).toLowerCase(); String bundleName = pkgName + ".resources" + resourceName; ResourceBundle bundle = null; try { bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault(), clazz.getClassLoader()); } catch (MissingResourceException e) { e.printStackTrace(); //XXX should failures be silent? } resourceMap.put(clazz, bundle); return bundle; } /** * Get the format string associated with <code>key</code> in the * given resource bundle. If <code>key</code> is not present in * the bundle, a default format string is returned which will * identify the missing key when printed. * * @param key the key of the format string to retrieve * @param bundle the bundle to retrieve the format string from * @return the format string. */ private static String getFormat(String key, ResourceBundle bundle) { String fmt = "no text found: \"" + key + "\" {0}"; if (bundle != null) { try { fmt = bundle.getString(key); } catch (MissingResourceException e) { } } return fmt; } /** * Print out string according to resourceBundle format. * * @param key the key of the format string to retrieve * @param bundle the bundle to retrieve the format string from */ public static String getString(String key, ResourceBundle bundle) { return MessageFormat.format(getFormat(key, bundle), null); } /** * Print out string according to resourceBundle format. * * @param key the key of the format string to retrieve * @param bundle the bundle to retrieve the format string from * @param val the value to substitute into the {0} parameter */ public static String getString(String key, ResourceBundle bundle, Object val) { return MessageFormat.format(getFormat(key, bundle), new Object[]{val}); } /** * Print out string according to resourceBundle format. * * @param key the key of the format string to retrieve * @param bundle the bundle to retrieve the format string from * @param val1 the value to substitute into the {0} parameter * @param val2 the value to substitute into the {1} parameter */ public static String getString(String key, ResourceBundle bundle, Object val1, Object val2) { return MessageFormat.format(getFormat(key, bundle), new Object[]{val1, val2}); } /** * Print out string according to resourceBundle format. * * @param key the key of the format string to retrieve * @param bundle the bundle to retrieve the format string from * @param val1 the value to substitute into the {0} parameter * @param val2 the value to substitute into the {1} parameter * @param val3 the value to substitute into the {2} parameter */ public static String getString(String key, ResourceBundle bundle, Object val1, Object val2, Object val3) { return MessageFormat.format(getFormat(key, bundle), new Object[]{val1, val2, val3}); } }