package org.sugarj.driver.caching;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.sugarj.common.ATermCommands;
import org.sugarj.common.FileCommands;
import org.sugarj.common.path.Path;
import org.sugarj.common.path.RelativePath;
/**
* The key of some SDF module as needed for caching.
*
* Besides the actual SDF module, also the path for looking up
* referenced modules is stored here. This way we do not need
* to store a complete grammar, as represented by SDF definitions.
*
* @author Sebastian Erdweg <seba at informatik uni-marburg de>
*
*/
public class ModuleKey implements Externalizable {
private boolean checkGet;
public Map<String, Integer> moduleDeps;
public String body;
/**
* For deserialization only.
*/
public ModuleKey() {}
public ModuleKey(Map<String, Integer> moduleDeps, String body) {
this.moduleDeps = moduleDeps;
this.body = body;
}
public ModuleKey(Map<Path, Integer> dependentFiles, Pattern pat, IStrategoTerm module) throws IOException {
this.moduleDeps = new HashMap<String, Integer>();
this.body = ATermCommands.atermToString(module);
for (Map.Entry<Path, Integer> entry : dependentFiles.entrySet())
if (pat == null || pat.matcher(entry.getKey().getAbsolutePath()).matches())
if (FileCommands.exists(entry.getKey())) {
String cachePath;
if (entry.getKey() instanceof RelativePath)
cachePath = ((RelativePath) entry.getKey()).getRelativePath();
else
cachePath = entry.getKey().getAbsolutePath();
moduleDeps.put(cachePath, entry.getValue());
}
}
public boolean equals(Object o) {
if (!(o instanceof ModuleKey))
return false;
ModuleKey k = (ModuleKey) o;
if (!body.equals(k.body))
return false;
return (checkGet ? moduleDeps.equals(k.moduleDeps) : moduleDeps.keySet().equals(k.moduleDeps.keySet()));
}
public int hashCode() {
return moduleDeps.keySet().hashCode() + body.hashCode();
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
moduleDeps = new HashMap<String, Integer>();
int entries = in.readInt();
for (int i = 0; i < entries; i++) {
moduleDeps.put((String) in.readObject(), in.readInt());
}
body = (String) in.readObject();
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(moduleDeps.size());
for (Entry<String, Integer> entry : moduleDeps.entrySet()) {
out.writeObject(entry.getKey());
out.writeInt(entry.getValue());
}
out.writeObject(body);
}
void doGet() {
this.checkGet = true;
}
void doPut() {
this.checkGet = false;
}
}