package org.eclipse.emf.texo.generator;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.eclipse.xpand2.output.FileHandle;
/**
* Receives the output of a generate action and the target location. Reads the current source from there and merges the
* generation output and the current content.
*
* @author <a href="mtaal@elver.org">Martin Taal</a>
*/
public class PropertyMerger extends MergingOutputHandler {
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.texo.generator.MergingOutputHandler#merge(org.eclipse.xpand2.output.FileHandle)
*/
@Override
protected void merge(final FileHandle fileHandle) {
try {
final File targetFile = new File(fileHandle.getAbsolutePath());
final Properties currentProps = new Properties();
if (targetFile.exists()) {
final InputStream is = new FileInputStream(targetFile);
try {
currentProps.load(is);
} finally {
is.close();
}
}
final Properties newProps = new Properties();
// TODO: encoding?
final InputStream is = new ByteArrayInputStream(fileHandle.getBuffer().toString().getBytes());
try {
newProps.load(is);
} finally {
is.close();
}
newProps.putAll(currentProps);
final List<PropertyEntry> result = convertSort(newProps);
// find the list of prefixes
final List<String> prefixes = new ArrayList<String>();
String currentPrefix = null;
for (final PropertyEntry pe : result) {
if (pe.key.indexOf(".") == -1) { // a prefix //$NON-NLS-1$
if (currentPrefix == null) {
currentPrefix = pe.key;
prefixes.add(currentPrefix);
// handle the plural case
} else if (currentPrefix.compareTo(pe.key + "s") != 0) { //$NON-NLS-1$
if (pe.key.endsWith("s")) { //$NON-NLS-1$
final String shortPrefix = pe.key.substring(0, pe.key.length() - 1);
if (!prefixes.contains(shortPrefix)) {
currentPrefix = pe.key;
prefixes.add(currentPrefix);
}
} else {
currentPrefix = pe.key;
prefixes.add(currentPrefix);
}
}
}
}
final StringBuilder newContent = new StringBuilder();
for (final String prefix : prefixes) {
if (newContent.length() > 0) {
newContent.append("\n"); //$NON-NLS-1$
}
newContent.append("#\n"); //$NON-NLS-1$
newContent.append("# " + prefix + //$NON-NLS-1$
"\n"); //$NON-NLS-1$
newContent.append("#\n"); //$NON-NLS-1$
for (final PropertyEntry pe : result) {
if (pe.isWritten()) {
continue;
}
if (pe.key.compareTo(prefix) == 0 || pe.key.compareTo(prefix + "s") == 0 //$NON-NLS-1$
|| pe.key.startsWith(prefix + ".")) { //$NON-NLS-1$
newContent.append(pe.write() + "\n"); //$NON-NLS-1$
}
}
}
fileHandle.setBuffer(newContent);
} catch (final IllegalStateException c) {
throw c; // rethrow to prevent to many exceptions
} catch (final Exception e) {
// catch them all
throw new IllegalStateException("Exception while merging and saving property file " //$NON-NLS-1$
+ fileHandle.getAbsolutePath() + " " + e.getMessage() + " " + e, e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
/** Sort and return the properties in a list */
private List<PropertyEntry> convertSort(final Properties props) {
final List<PropertyEntry> result = new ArrayList<PropertyEntry>();
for (final Object keyObject : props.keySet()) {
final String key = (String) keyObject;
result.add(new PropertyEntry(key, props.getProperty(key)));
}
Collections.sort(result);
return result;
}
protected class PropertyEntry implements Comparable<PropertyEntry> {
private String key;
private String value;
private boolean written = false;
PropertyEntry(final String key, final String value) {
this.key = key;
this.value = value;
}
public int compareTo(final PropertyEntry o) {
// ensure that the ones with a dot are placed later
return key.replaceAll("\\.", //$NON-NLS-1$
"z").compareTo( //$NON-NLS-1$
o.key.replaceAll("\\.", //$NON-NLS-1$
"z")); //$NON-NLS-1$
}
private String write() {
written = true;
return key + " = " + value; //$NON-NLS-1$
}
/**
* @return the written
*/
public boolean isWritten() {
return written;
}
}
@Override
protected String[] getSupportedExtensions() {
return new String[] { ".properties" }; //$NON-NLS-1$
}
}