org.glassfish.appclient.common.Util Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2019] Payara Foundation and/or affiliates
package org.glassfish.appclient.common;
import com.sun.enterprise.deployment.ApplicationClientDescriptor;
import com.sun.enterprise.util.io.FileUtils;
import org.glassfish.deployment.common.ModuleDescriptor;
import org.glassfish.deployment.common.RootDeploymentDescriptor;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*Implements several stateless utility methods.
*
* @author tjquinn
*/
public class Util {
/** Pattern to match placeholders in dynamic document templates.
*The pattern specifies a non-aggressive match for ${token-name} strings.
*(Non-aggressive means the pattern consumes as little of the input string
*as possible in searching for a match.) The pattern also stores the token
*name in group 1 of the pattern matcher.
*/
private static Pattern placeholderPattern = Pattern.compile("\\$\\{(.*?)\\}");
/** used in finding the name of the first class in a jar file */
private static final String CLASS_SUFFIX = ".class";
/** size of buffer used to load resources */
private static final int BUFFER_SIZE = 1024;
/** Creates a new instance of Util */
public Util() {
}
/**
*Searches for placeholders of the form ${token-name} in the input String, retrieves
*the property with name token-name from the Properties object, and (if
*found) replaces the token in the input string with the property value.
*@param s String possibly containing tokens
*@param values Properties object containing name/value pairs for substitution
*@return the original string with tokens substituted using their values
*from the Properties object
*/
public static String replaceTokens(String s, Properties values) {
Matcher m = placeholderPattern.matcher(s);
StringBuffer sb = new StringBuffer();
/*
*For each match, retrieve group 1 - the token - and use its value from
*the Properties object (if found there) to replace the token with the
*value.
*/
while (m.find()) {
String propertyName = m.group(1);
String propertyValue = values.getProperty(propertyName);
if (propertyValue != null) {
/*
*The next line quotes any $ signs in the replacement string
*so they are not interpreted as meta-characters by the regular expression
*processor's appendReplacement. The replaceAll replaces all occurrences
*of $ with \$. The extra slashes are needed to quote the backslash
*for the Java language processor and then again for the regex
*processor (!).
*/
String adjustedPropertyValue = propertyValue.replaceAll("\\$", "\\\\\\$");
String x = s.substring(m.start(),m.end());
try {
m.appendReplacement(sb, adjustedPropertyValue);
} catch (IllegalArgumentException iae) {
System.err.println("**** appendReplacement failed: segment is " + x + "; original replacement was " + propertyValue + " and adj. replacement is " + adjustedPropertyValue + "; exc follows");
throw iae;
}
}
}
/*
*There are no more matches, so append whatever remains of the matcher's input
*string to the output.
*/
m.appendTail(sb);
return sb.toString();
}
/**
*Returns the main class name for the app client represented by the module descriptor.
*@param moduleDescr the module descriptor for the app client of interest
*@return main class name of the app client
*/
public static String getMainClassNameForAppClient(ModuleDescriptor moduleDescr) throws IOException, FileNotFoundException, org.xml.sax.SAXParseException {
RootDeploymentDescriptor bd = moduleDescr.getDescriptor();
ApplicationClientDescriptor acDescr = (ApplicationClientDescriptor) bd;
String mainClassName = acDescr.getMainClassName();
return mainClassName;
}
/**
*Writes the provided text to a temporary file marked for deletion on exit.
*@param content the content to be written
*@param prefix prefix for the temp file, conforming to the File.createTempFile requirements
*@param suffix suffix for the temp file
*@param retainFile whether to keep the file
*@return File object for the newly-created temp file
*@throws IOException for any errors writing the temporary file
*@throws FileNotFoundException if the temp file cannot be opened for any reason
*/
public static File writeTextToTempFile(String content, String prefix, String suffix, boolean retainFile) throws IOException, FileNotFoundException {
File result = File.createTempFile(prefix, suffix);
if ( ! retainFile) {
FileUtils.deleteOnExit(result);
}
try (BufferedWriter wtr =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(result)))) {
wtr.write(content);
}
return result;
}
/**
*Writes the provided text to a temporary file marked for deletion on exit.
*@param content the content to be written
*@param prefix for the temp file, conforming to the File.createTempFile requirements
*@param suffix for the temp file
*@return File object for the newly-created temp file
*@throws IOException for any errors writing the temporary file
*@throws FileNotFoundException if the temp file cannot be opened for any reason
*/
public static File writeTextToTempFile(String content, String prefix, String suffix) throws IOException, FileNotFoundException {
return writeTextToTempFile(content, prefix, suffix, false);
}
/**
*Finds the jar file or directory that contains the current class and returns its URI.
*@param target the class, the containing jar file or directory of which is of interest
*@return URL to the containing jar file or directory
*/
public static URL locateClass(Class target) {
return target.getProtectionDomain().getCodeSource().getLocation();
}
/**
*Retrieves a resource as a String.
*
*This method does not save the template in a cache. Use the instance method
*getTemplate for that purpose.
*
*@param contextClass a class, the class loader of which should be used for searching for the template
*@param resourcePath the path of the resource to load, relative to the contextClass
*@return the resource's contents
*@throws IOException if the resource is not found or in case of error while loading it
*/
public static String loadResource(Class contextClass, String resourcePath) throws IOException {
String result = null;
InputStream is = null;
BufferedReader reader = null;
try {
is = contextClass.getResourceAsStream(resourcePath);
if (is == null) {
throw new IOException("Could not locate the requested resource relative to class " + contextClass.getName());
}
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(is));
int charsRead;
char [] buffer = new char [BUFFER_SIZE];
while ((charsRead = reader.read(buffer)) != -1) {
sb.append(buffer, 0, charsRead);
}
result= sb.toString();
return result;
} catch (IOException ioe) {
throw new IOException("Error loading resource " + resourcePath, ioe);
} finally {
if (reader != null) {
reader.close();
}
}
}
/**
*Copy an existing file into a temporary file.
*@param inputFile existing file
*@return File object for the temporary file
*/
public static File copyToTempFile(File inputFile, String prefix, String suffix, boolean retainFile) throws IOException, FileNotFoundException {
File result = null;
BufferedInputStream is = null;
BufferedOutputStream os = null;
try {
result = File.createTempFile(prefix, suffix);
if ( ! retainFile) {
FileUtils.deleteOnExit(result);
}
os = new BufferedOutputStream(new FileOutputStream(result));
is = new BufferedInputStream(new FileInputStream(inputFile));
byte [] buffer = new byte[BUFFER_SIZE];
int bytesRead = 0;
while ( (bytesRead = is.read(buffer) ) != -1) {
os.write(buffer, 0, bytesRead);
}
return result;
} finally {
try {
if (is != null) {
is.close();
}
} finally {
if (os != null) {
os.close();
}
}
}
}
/**
*Returns a codeBase expression, usable in a policy file, for the specified
*URL.
*@param classPathElement the URL to be converted
*@return the codeBase expression
*/
public static String URLtoCodeBase(URL classPathElement) throws FileNotFoundException, URISyntaxException {
/*
*We can assume the URL specifies a file.
*/
File file = new File(classPathElement.toURI());
if (! file.exists()) {
/*
*If we cannot locate the file, it may be a jar listed in the
*manifest's Class-Path of a top-level archive. The spec does
*not require containers to handle such jars, so just
*return null.
*/
//throw new FileNotFoundException(classPathElement.toURI().toASCIIString());
return null;
}
/*
*The format of the codebase is different for a directory vs. a jar
*file. Also note that the codebase must use the platform-neutral
*"forward-slash" notation.
*/
String result;
if (file.isDirectory()) {
result = classPathElement.getProtocol() + ":" + classPathElement.toURI().getPath() + "-";
} else {
result = classPathElement.getProtocol() + ":" + classPathElement.toURI().getPath();
}
return result;
}
}