/* * Copyright 2008 the original author or authors. * * 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.rioproject.impl.config; import org.rioproject.opstring.ServiceElement; import org.rioproject.resolver.Artifact; import org.rioproject.resolver.Resolver; import org.rioproject.resolver.ResolverException; import org.rioproject.resolver.ResolverHelper; import org.rioproject.util.PropertyHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; /** * Utility for accessing configuration arguments. * * @author Dennis Reedy */ public class ConfigHelper { public static final String CLASSPATH_RESOURCE="classpath:"; public static final String FILE_RESOURCE="file:"; private static Logger logger = LoggerFactory.getLogger(ConfigHelper.class); /** * Get configuration arguments to create a * {@link net.jini.config.Configuration} object * * @param service The {@code ServiceElement} containing details * to create a {@link net.jini.config.Configuration} * * @return * <ul> * <li>If the first parameter of the enclosed configuration args parameters is an {@link Artifact}, * resolve the {@code Artifact}, and returned the resolved file. * <li>If the first parameter of the enclosed configuration args parameters is a "-", * return the configuration args intact. * <li>If the first element of the enclosed configuration args parameter begins with * <tt>classpath:</tt>, load the {@link java.net.URL} of the configuration * file as a resource using the current context classloader, and return the * {@link java.net.URL#toString()} of the loaded resource. Only the first * element of the args parameter is used to construct the configuration * argument. * <li>If the first element of the enclosed configuration args parameter begins with * <tt>file:</tt>, return the canonical path of the file. If the parameter * does not include a leading {@link java.io.File#separator}, the file * location will be considered relative to the current working directory. * If there are any system property elements defined in the args element, * they will be translated to the corresponding system properties of the * running JVM. * <li>If the first element of the enclosed configuration args parameter ends with .config or * .groovy, return the args parameter intact. If there are any system * property elements defined in the args element, they will be translated * to the corresponding system properties of the running JVM. * <li>Otherwise, create a temporary file containing the contents of the * args value and return the canonical path of the created file as the * configuration argument * </ul> * * @throws IllegalArgumentException if the service parameter is null * @throws IOException if there are errors accessing the file system */ public static String[] getConfigArgs(final ServiceElement service) throws IOException { return getConfigArgs(service, Thread.currentThread().getContextClassLoader()); } /** * Get configuration arguments to create a * {@link net.jini.config.Configuration} object * * @param service The {@code ServiceElement} containing details * to create a {@link net.jini.config.Configuration} * @param cl The ClassLoader to use if resources need to be loaded. * * @return * <ul> * <li>If the first parameter of the enclosed configuration args parameters is an {@link Artifact}, * resolve the {@code Artifact}, and returned the resolved file. * <li>If the first parameter of the enclosed configuration args parameters is a "-", * return the configuration args intact. * <li>If the first element of the enclosed configuration args parameter begins with * <tt>classpath:</tt>, load the {@link java.net.URL} of the configuration * file as a resource using the current context classloader, and return the * {@link java.net.URL#toString()} of the loaded resource. Only the first * element of the args parameter is used to construct the configuration * argument. * <li>If the first element of the enclosed configuration args parameter begins with * <tt>file:</tt>, return the canonical path of the file. If the parameter * does not include a leading {@link java.io.File#separator}, the file * location will be considered relative to the current working directory. * If there are any system property elements defined in the args element, * they will be translated to the corresponding system properties of the * running JVM. * <li>If the first element of the enclosed configuration args parameter ends with .config or * .groovy, return the args parameter intact. If there are any system * property elements defined in the args element, they will be translated * to the corresponding system properties of the running JVM. * <li>Otherwise, create a temporary file containing the contents of the * args value and return the canonical path of the created file as the * configuration argument * </ul> * * @throws IllegalArgumentException if the service parameter is null, or if a * ClassLoader is not provided * @throws IOException if there are errors accessing the file system */ public static String[] getConfigArgs(final ServiceElement service, final ClassLoader cl) throws IOException { if(service==null) throw new IllegalArgumentException("service cannot be null"); String[] args = service.getServiceBeanConfig().getConfigArgs(); if(cl==null) throw new IllegalArgumentException("You must provide a ClassLoader"); if (args[0].equals("-")) return args; if(Artifact.isArtifact(args[0])) { logger.debug("Loading configuration {} as an artifact", args[0]); URL configLocation = null; try { Resolver resolver = ResolverHelper.getResolver(); Artifact artifact = new Artifact(args[0]); configLocation = resolver.getLocation(artifact.getGAV(), artifact.getType(), service.getRemoteRepositories()); return new String[]{new File(configLocation.toURI()).getPath()}; } catch(ResolverException e) { throw new IOException("Could not resolve "+args[0], e); } catch (URISyntaxException e) { throw new IOException("Could load resolved configuration from "+configLocation.toExternalForm(), e); } } if(args[0].startsWith(CLASSPATH_RESOURCE)) { logger.debug("Loading configuration {} as a classpath resource", args[0]); String classPathArgs = args[0].substring(CLASSPATH_RESOURCE.length(), args[0].length()); List<String> list = new ArrayList<String>(); for(String s : classPathArgs.split(",")) { URL url = cl.getResource(s); if(url==null) { throw new IOException("Unable to load ["+s+"] " + "configuration file as a classpath " + "resource using classloader ["+cl+"]"); } list.add(url.toString()); } return list.toArray(new String[list.size()]); } if(args[0].startsWith(FILE_RESOURCE) || args[0].endsWith(".config") || args[0].endsWith(".groovy")) { logger.debug("Loading configuration {} as a file resource", args[0]); String fileArg; if(args[0].startsWith(FILE_RESOURCE)) { if(args[0].startsWith(FILE_RESOURCE+"//")) { String s = FILE_RESOURCE+"//"; fileArg = args[0].substring(s.length(), args[0].length()); } else { fileArg = args[0].substring(FILE_RESOURCE.length(), args[0].length()); } } else { fileArg = args[0]; } String fileArgs = PropertyHelper.expandProperties(fileArg, PropertyHelper.PARSETIME); List<String> list = new ArrayList<String>(); for(String fileName : fileArgs.split(",")) { if(fileName.startsWith("http:") || fileName.startsWith("https:")) { list.add(fileName); continue; } File f = new File(fileName); if(!f.isAbsolute()) { fileName = System.getProperty("user.dir")+File.separator+fileName; f = new File(fileName); } if(!f.exists()) throw new FileNotFoundException("Unable to load declared configuration " + "file ["+fileArg+"], resolved " + "as ["+fileName+"]. File does not exist"); list.add(fileName); } return list.toArray(new String[list.size()]); } if(isGroovy(args)) { return args; } else { String extension = ".config"; File tmp = File.createTempFile("tmp", extension); tmp.deleteOnExit(); BufferedWriter out = null; try { out = new BufferedWriter(new FileWriter(tmp)); for (String arg : args) { out.write(arg); } } finally { if (out != null) out.close(); } return (new String[]{tmp.getCanonicalPath()}); } } private static boolean isGroovy(final String... args) { StringBuilder buff = new StringBuilder(); for(String s : args) buff.append(s); boolean isGroovy = false; StringTokenizer tok = new StringTokenizer(buff.toString(), "\n"); while(tok.hasMoreTokens()) { String line = tok.nextToken(); if(line.contains("{")) { if(line.contains("class")) isGroovy = true; break; } } return isGroovy; } }