use of net.sourceforge.processdash.data.SaveableData in project processdash by dtuma.
the class DataRepository method dumpRepository.
/** Print textual information about the data elements in the repostory.
*
* @param out a stream to write the information to
* @param filt a collection of prefixes that should be exported
* @param style the style of information to print, should be one of
* DUMP_STYLE_TEXT, DUMP_STYLE_DATA, or DUMP_STYLE_CALC.
*/
public void dumpRepository(PrintWriter out, Collection filt, int style) {
gc(null);
Iterator k = getKeys(filt, null);
// print out all element values.
while (k.hasNext()) {
String name = (String) k.next();
if (Filter.matchesFilter(filt, name)) {
try {
DataElement de = getOrCreateDefaultDataElement(name);
if (de == null || de.datafile == null)
continue;
SaveableData sd;
if (style == DUMP_STYLE_CALC)
sd = de.getValue();
else
sd = de.getSimpleValue();
if (sd == null)
continue;
String value = null;
if (style != DUMP_STYLE_TEXT) {
value = sd.saveString();
} else if (sd instanceof DateData) {
value = ((DateData) sd).formatDate();
} else if (sd instanceof StringData) {
value = StringData.escapeString(((StringData) sd).getString());
} else
value = sd.toString();
if (style == DUMP_STYLE_TEXT) {
if (name.indexOf(',') != -1)
name = EscapeString.escape(name, '\\', ",", "c");
out.println(name + "," + value);
} else {
out.println(name.substring(1) + "==" + value);
}
} catch (Exception e) {
// System.err.println("Data error:"+e.toString()+"
// for:"+name);
}
}
Thread.yield();
}
}
use of net.sourceforge.processdash.data.SaveableData in project processdash by dtuma.
the class DataRepository method putGlobalValue.
private void putGlobalValue(String name, Object valueObj) {
DataElement e = (DataElement) data.get(name);
if (e != null && e.getValue() != null)
// don't overwrite existing values?
return;
String localName = name.substring(1);
valueObj = DataRenamingOperation.maybeInitRenamingOperation(localName, valueObj);
globalDataDefinitions.put(localName, valueObj);
definitionsDirty = true;
if (e != null) {
SaveableData o = instantiateValue(name, "", valueObj, false);
if (o != null)
putValue(name, o, IS_DEFAULT_VAL);
} else if (!(valueObj instanceof DataRenamingOperation)) {
if (globalDataIsMounted)
repositoryListenerList.dispatchAdded(name);
}
}
use of net.sourceforge.processdash.data.SaveableData in project processdash by dtuma.
the class DataRepository method putValue.
protected void putValue(String name, SaveableData value, boolean isDefaultValue, boolean checkDatafileModification) {
if (recursion_depth >= MAX_RECURSION_DEPTH) {
System.err.println("DataRepository detected circular dependency in data,\n" + " bailed out after " + MAX_RECURSION_DEPTH + " iterations.");
new Exception().printStackTrace(System.err);
return;
}
try {
recursion_depth++;
DataElement d = (DataElement) data.get(name);
if (d != null) {
// change the value of the data element.
SaveableData oldValue = d.getValue();
d.setValue(value, isDefaultValue);
// possibly mark the datafile as modified.
if (checkDatafileModification && d.datafile != null && value != oldValue && (oldValue == null || value == null || !value.saveString().equals(oldValue.saveString()))) {
if (PHANTOM_DATAFILES.contains(d.datafile)) {
// move the item OUT of the phantom datafile so it will be saved.
d.datafile = guessDataFile(name, REQUIRE_WRITABLE);
d.isDefaultName = false;
}
datafileModified(d.datafile);
}
// possibly throw away the old value.
if (oldValue != null && oldValue != value)
try {
oldValue.dispose();
} catch (Exception ex) {
}
// notify any listeners registed for the change
dataNotifier.dataChanged(name, d);
// check if this element is no longer needed.
maybeDelete(name, d, false);
} else {
// if the value was not already in the repository, add it.
// if we're writing a default value, it must be for a default name.
boolean isDefaultName = isDefaultValue;
// determine the data file for this element.
DataFile f = guessDataFile(name, REQUIRE_WRITABLE);
// a default value that has not yet been lazily constructed?)
if (!isDefaultValue && f != null && f.inheritedDefinitions != null) {
String localName = name.substring(f.prefix.length() + 1);
isDefaultName = f.inheritedDefinitions.containsKey(localName);
}
try {
add(name, isDefaultName, value, isDefaultValue, f, DO_NOTIFY);
if (!isDefaultValue && (isDefaultName || value != null) && checkDatafileModification)
datafileModified(f);
} catch (DataElementAlreadyExistsException e) {
// this rare occurrence means that some other thread created this
// DataElement in the time since we tried to retrieve it and found
// that it was missing. The best course of action is to retry the
// operation.
putValue(name, value, isDefaultValue, checkDatafileModification);
}
}
} finally {
recursion_depth--;
}
}
use of net.sourceforge.processdash.data.SaveableData in project processdash by dtuma.
the class DataRepository method maybeCreateDefaultData.
/** If the name designates a lazy default value, automatically creates that
* value and returns it. Otherwise, returns null.
*
* @throws DataElementAlreadyExistsException if a data element with
* that name already exists
*/
private DataElement maybeCreateDefaultData(String name) throws DataElementAlreadyExistsException {
if (name == null)
return null;
DataFile f = guessDataFile(name, DO_NOT_REQUIRE_WRITABLE);
if (f == null)
return null;
else if (f.isImported)
return getImportedFileNullElement(f);
else if (f.inheritedDefinitions == null)
return null;
String localName = name.substring(f.prefix.length() + 1);
Object defaultValueObject = f.inheritedDefinitions.get(localName);
if (defaultValueObject == null)
return null;
SaveableData value = instantiateValue(name, f.prefix, defaultValueObject, !f.canWrite);
return janitor.itemWasCreated(add(name, IS_DEFAULT_NAME, value, IS_DEFAULT_VAL, f, DO_NOT_NOTIFY));
}
use of net.sourceforge.processdash.data.SaveableData in project processdash by dtuma.
the class DataRepository method saveDatafile.
/** Saves a set of data to the appropriate data file.
*
* @param datafile the datafile to save
*/
private void saveDatafile(DataFile datafile) {
if (datafile == null || datafile.file == null || datafile.isRemoved || saveDisabled)
return;
// this flag should stay false until we are absolutely certain
// that we have successfully saved the datafile.
boolean saveSuccessful = false;
// the same datafile concurrently.
synchronized (datafile) {
try {
// debug("saveDatafile");
Set valuesToSave = new TreeSet();
// if the data file has an include statement, lookup the associated
// default values defined by the included file.
Map defaultValues = datafile.inheritedDefinitions;
if (defaultValues == null)
defaultValues = Collections.EMPTY_MAP;
// optimistically mark the datafile as "clean" at the beginning of
// the save operation. This way, if the datafile is modified
// during the save operation, the dirty changes will take effect,
// and the datafile will be saved again in the future.
datafile.dirtyCount = 0;
int prefixLength = datafile.prefix.length() + 1;
for (Iterator i = getInternalKeys(); i.hasNext(); ) {
String name = (String) i.next();
DataElement element = (DataElement) data.get(name);
if (element == null || element.datafile != datafile || element.isDefaultValue())
// DataFile, or if it has a default value, skip it.
continue;
SaveableData value = element.getValue();
String valStr = null;
boolean editable = true;
if (value != null) {
valStr = value.saveString();
editable = value.isEditable();
} else if (element.isDefaultName()) {
// store the fact that the default is overwritten with null
valStr = "null";
}
if (valStr == null || valStr.length() == 0)
continue;
name = name.substring(prefixLength).replace('=', EQUALS_SIGN_REPL);
valuesToSave.add(name + (editable ? "=" : "==") + valStr);
}
// Write the saved values
RobustFileOutputStream rfos;
BufferedWriter out;
try {
rfos = new RobustFileOutputStream(datafile.file);
} catch (IOException e) {
logger.log(Level.SEVERE, "Encountered exception while opening " + datafile.file.getPath() + "; save aborted", e);
return;
}
try {
String encoding = getDatasetEncoding();
out = new BufferedWriter(new OutputStreamWriter(new NullByteWatcher(rfos), encoding));
// if the data file has an include statement, write it to the file
if (datafile.inheritsFrom != null) {
out.write(includeTag + datafile.inheritsFrom);
out.newLine();
}
// If the data file has a prefix, write it as a comment to the file
if (datafile.prefix != null && datafile.prefix.length() > 0) {
out.write("= Data for " + datafile.prefix);
out.newLine();
}
for (Iterator i = valuesToSave.iterator(); i.hasNext(); ) {
out.write((String) i.next());
out.newLine();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Encountered exception while writing to " + datafile.file.getPath() + "; save aborted", e);
try {
rfos.abort();
} catch (Exception ex) {
}
return;
}
try {
// Close output file
out.flush();
out.close();
saveSuccessful = true;
System.err.println("Saved " + datafile.file.getPath());
} catch (IOException e) {
logger.log(Level.SEVERE, "Encountered exception while closing " + datafile.file.getPath() + "; save aborted", e);
try {
rfos.abort();
} catch (Exception ex) {
}
}
} finally {
// if we couldn't successfully save the datafile, mark it as dirty.
if (!saveSuccessful)
datafile.dirtyCount = 1000;
}
}
}
Aggregations