Skip to content

Commit

Permalink
towards more powerful ConfigClients
Browse files Browse the repository at this point in the history
  • Loading branch information
g3force committed Oct 28, 2015
1 parent bbb6fdb commit 2598e3f
Show file tree
Hide file tree
Showing 8 changed files with 536 additions and 223 deletions.
189 changes: 135 additions & 54 deletions src/main/java/com/github/configurable/AConfigClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@
*/
package com.github.configurable;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.configuration.CombinedConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.tree.NodeCombiner;
import org.apache.commons.configuration.tree.UnionCombiner;
import org.apache.log4j.Logger;


/**
Expand All @@ -21,122 +32,192 @@
*/
public abstract class AConfigClient implements IConfigClient
{
// --------------------------------------------------------------------------
// --- variables and constants ----------------------------------------------
// --------------------------------------------------------------------------
@SuppressWarnings("unused")
private static final Logger log = Logger.getLogger(AConfigClient.class.getName());

private static final String XML_ENCODING = "UTF-8";

private final String name;
private final String configPath;
private final String configKey;
private final String defaultValue;
private final boolean editable;
private final List<IConfigObserver> observers = new CopyOnWriteArrayList<IConfigObserver>();


// --------------------------------------------------------------------------
// --- constructors ---------------------------------------------------------
// --------------------------------------------------------------------------
private final String path;
private final List<IConfigObserver> observers = new CopyOnWriteArrayList<IConfigObserver>();

private HierarchicalConfiguration config = new HierarchicalConfiguration();


/**
* @param name
* @param configPath
* @param configKey
* @param defaultValue
* @param editable
* @param path
*/
public AConfigClient(final String name, final String configPath, final String configKey, final String defaultValue,
final boolean editable)
public AConfigClient(final String name, final String path)
{
super();
this.name = name;
this.configPath = configPath;
this.configKey = configKey;
this.defaultValue = defaultValue;
this.editable = editable;
this.path = path;
}


// --------------------------------------------------------------------------
// --- methods --------------------------------------------------------------
// --------------------------------------------------------------------------
@Override
public void onReload(final HierarchicalConfiguration freshConfig)
public HierarchicalConfiguration getFileConfig()
{
onLoad(freshConfig);

for (IConfigObserver observer : observers)
String fileName = name + ".xml";
String filePath = Paths.get(path, fileName).toString();
XMLConfiguration cfg = new XMLConfiguration();
try
{
observer.onReload(freshConfig);
cfg.setDelimiterParsingDisabled(true);
cfg.setFileName(fileName);
cfg.load(filePath);
} catch (final ConfigurationException err)
{
log.error("Unable to load config '" + name + "' from '" + filePath + "':", err);
}

return cfg;
}


/**
* @author Nicolai Ommer <nicolai.ommer@gmail.com>
*/
@Override
public HierarchicalConfiguration getCombinedConfig()
{
// Create and initialize the node combiner
NodeCombiner combiner = new UnionCombiner();
combiner.addListNode("table"); // mark table as list node
// this is needed only if there are ambiguities

// Construct the combined configuration
CombinedConfiguration cc = new CombinedConfiguration(combiner);
cc.addConfiguration(getLocalConfig());
cc.addConfiguration(getFileConfig());

return cc;
}


@Override
public HierarchicalConfiguration getDefaultConfig()
public void loadCombinedConfig()
{
return null;
config = getCombinedConfig();
notifyLoadConfig();
}


/**
* @param observer
* @author Nicolai Ommer <nicolai.ommer@gmail.com>
*/
public void addObserver(final IConfigObserver observer)
@Override
public void loadFileConfig()
{
observers.add(observer);
config = getFileConfig();
notifyLoadConfig();
}


/**
* @param observer
* @author Nicolai Ommer <nicolai.ommer@gmail.com>
*/
public void removeObserver(final IConfigObserver observer)
@Override
public void loadLocalConfig()
{
observers.remove(observer);
config = getLocalConfig();
notifyLoadConfig();
}


/**
* @author Nicolai Ommer <nicolai.ommer@gmail.com>
*/
public void notifyLoadConfig()
{
for (IConfigObserver o : observers)
{
o.onLoad(config);
}
}


/**
* @author Nicolai Ommer <nicolai.ommer@gmail.com>
* @return
*/
@Override
public void clearObservers()
public boolean saveCurrentConfig()
{
observers.clear();
String fileName = name + ".xml";
String filePath = Paths.get(path, fileName).toString();

FileOutputStream targetFile = null;
OutputStream prettyOut = null;
try
{
targetFile = new FileOutputStream(filePath, false);

prettyOut = new PrettyXMLOutputStream(targetFile, XML_ENCODING);
XMLConfiguration xmlConfig = new XMLConfiguration(config);
xmlConfig.save(prettyOut, XML_ENCODING);

} catch (final ConfigurationException err)
{
log.error("Unable to save config '" + name + "' to '" + filePath + "'.");
return false;
} catch (final FileNotFoundException err)
{
log.error("Unable to access the file to save the config to: " + filePath, err);
} finally
{
try
{
if (prettyOut != null)
{
prettyOut.close();
}
if (targetFile != null)
{
targetFile.close();
}
} catch (IOException err)
{
log.error("Error while saving config: Unable to close streams!", err);
}
}

return true;
}


// --------------------------------------------------------------------------
// --- getter/setter --------------------------------------------------------
// --------------------------------------------------------------------------
@Override
public final String getName()
public void addObserver(final IConfigObserver observer)
{
return name;
observers.add(observer);
}


@Override
public final String getConfigPath()
public void removeObserver(final IConfigObserver observer)
{
return configPath;
observers.remove(observer);
}


@Override
public final String getConfigKey()
public final String getName()
{
return configKey;
return name;
}


@Override
public final String getDefaultValue()
public final String getPath()
{
return defaultValue;
return path;
}


@Override
public final boolean isEditable()
public final HierarchicalConfiguration getCurrentConfig()
{
return editable;
return config;
}
}
Loading

0 comments on commit 2598e3f

Please sign in to comment.