blob: 9745545fd6dd0d87287b9110844ab14ad7f8b7b7 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* VMware Inc. - initial contribution
*******************************************************************************/
package org.eclipse.virgo.kernel.config.internal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.virgo.util.common.StringUtils;
import org.eclipse.virgo.util.io.FileSystemUtils;
import org.eclipse.virgo.util.io.IOUtils;
import org.osgi.framework.Constants;
import org.osgi.service.cm.ConfigurationAdmin;
/**
* Implementation of {@link PropertiesSource} that loads all the configuration supplied by the kernel user.
*
* <p/>
*
* User configuration is loaded from all properties files found in the directories listed in the
* {@link KernelConfiguration#getConfigDirectories() configuration directories}.
*
* <strong>Concurrent Semantics</strong><br />
*
* Threadsafe.
*
*/
final class UserConfigurationPropertiesSource implements PropertiesSource {
private static final String PROPERTIES_FILE_SUFFIX = ".properties";
private static final FilenameFilter PROPERTIES_FILENAME_FILTER = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(PROPERTIES_FILE_SUFFIX);
}
};
private final File[] kernelConfigDirectories;
/**
* Creates a new <code>UserConfigurationPropertiesSource</code> that loads config files from the supplied user
* config directories.
*
* @param kernelConfigDirectories the directories containing the users kernel config files.
*/
public UserConfigurationPropertiesSource(File[] kernelConfigDirectories) {
this.kernelConfigDirectories = kernelConfigDirectories;
}
/**
* {@inheritDoc}
*/
public Map<String, Properties> getConfigurationProperties() {
Map<String, Properties> result = new TreeMap<String, Properties>();
for (File dir : this.kernelConfigDirectories) {
File[] configFiles = getPropertiesFiles(dir);
for (File file : configFiles) {
Properties properties = readPropertiesFromFile(file);
String pid = computePid(file, properties, result.keySet());
// Last pid encountered wins; no merging is performed
result.put(pid, properties);
}
}
return result;
}
private static File[] getPropertiesFiles(File directory) {
if (directory.isDirectory()) {
return FileSystemUtils.listFiles(directory, PROPERTIES_FILENAME_FILTER);
}
return new File[0];
}
private Properties readPropertiesFromFile(File file) {
if (!file.exists()) {
return null;
}
Properties props = new Properties();
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
props.load(is);
} catch (IOException ioe) {
// silently ignored
return null;
} finally {
IOUtils.closeQuietly(is);
}
return props;
}
private static String createPid(final File file) {
return trimExtension(file.getName());
}
private static String trimExtension(final String name) {
int lpDot = name.lastIndexOf('.');
return lpDot == -1 ? name : name.substring(0, lpDot);
}
private String computePid(File file, Properties properties, Set<String> existingPids) {
// check for factory pid in properties
String pid = properties.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID);
if (StringUtils.hasText(pid)) {
// need something unique - so multiple factory pids can be deployed
return pid + "-" + createPid(file);
}
// account for service.pid as a property in the file
pid = properties.getProperty(Constants.SERVICE_PID);
if (StringUtils.hasText(pid)) {
return pid;
}
return createPid(file);
}
}