package org.objectstyle.wolips.wodclipse.core.completion; import java.io.ByteArrayOutputStream; import java.io.InputStream; import org.eclipse.core.resources.IFile; import org.eclipse.jface.text.IDocument; import org.objectstyle.wolips.wodclipse.core.util.WodModelUtils; public abstract class AbstractCacheEntry<T> { private WodParserCache _cache; private T _model; private IFile _file; private String _contents; private IDocument _document; private boolean _documentChanged; private long _lastParseTime; private boolean _validated; public AbstractCacheEntry(WodParserCache cache) { _cache = cache; clear(); } public WodParserCache getCache() { return _cache; } public void deleteProblems() { if (_file != null && _file.exists()) { WodModelUtils.deleteProblems(_file); } } public abstract void validate() throws Exception; public void _setModel(T model) { // System.out.println("AbstractCacheEntry._setModel: " + this + " => " + model); _model = model; } public boolean isValidated() { return _validated; } public void setValidated(boolean validated) { _validated = validated; } public void setModel(T model) { _model = model; } public T getModel() throws Exception { synchronized (getCache()) { T model = _getModel(); if (model == null) { getCache().parse(); getCache().validate(false, true); model = _getModel(); } return model; } } public T _getModel() { return _model; } public synchronized void setContents(String contents) { _setContents(contents); _setModel(null); _file = null; //System.out.println("AbstractCacheEntry.setContents: b " + _file); _document = null; _documentChanged = true; } public void _setContents(String contents) { _contents = contents; } public String getContents() { return _contents; } public synchronized void setDocument(IDocument document) { _document = document; _documentChanged = true; } public void _setDocument(IDocument document) { _document = document; } public IDocument getDocument() { return _document; } public IFile getFile() { return _file; } public void setFile(IFile file) { // System.out.println("AbstractCacheEntry.setFile: c " + file); _file = file; } protected abstract T _parse(String contents) throws Exception; protected String _process(String contents) { return contents; } protected synchronized T _parse(String contents, boolean updateCache) throws Exception { //System.out.println("WodParserCacheEntry._parse: " + getFile() + ", " + updateCache); String processedContents = _process(contents); if (updateCache) { _contents = processedContents; } T model = _parse(processedContents); if (updateCache) { //System.out.println("WodParserCacheEntry._parse: set model (String) = " + model); _setModel(model); _documentChanged = false; _validated = false; getCache()._setValidated(false); } return model; } public synchronized T parse(String contents, boolean updateCache) throws Exception { T model = _parse(contents, updateCache); if (updateCache) { //System.out.println("WodParserCacheEntry.parse: set model = " + model); _setModel(model); _documentChanged = false; _lastParseTime = System.currentTimeMillis(); _validated = false; getCache()._setValidated(false); } return model; } protected T _parse(IDocument document, boolean updateCache) throws Exception { T model = _parse(document.get(), updateCache); return model; } public synchronized T parse(IDocument document, boolean updateCache) throws Exception { T model = _parse(document, updateCache); if (updateCache) { //System.out.println("WodParserCacheEntry.parse: set model (doc) = " + model); _setModel(model); _documentChanged = false; if (_file != null && _file.exists()) { _lastParseTime = _file.getModificationStamp(); } _validated = false; getCache()._setValidated(false); } return model; } protected T _parse(IFile file, boolean updateCache) throws Exception { String contents; InputStream in = file.getContents(); try { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { int len = 0; byte[] buf = new byte[1024 * 8]; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); } contents = out.toString(file.getCharset()); } finally { out.close(); } } finally { in.close(); } try { T model = _parse(contents, updateCache); return model; } catch (Throwable t) { throw new RuntimeException("Failed to parse '" + file + "'.", t); } } public synchronized T parse(IFile file, boolean updateCache) throws Exception { //System.out.println("AbstractCacheEntry.parse: " + file); T model = _parse(file, updateCache); if (updateCache) { //System.out.println("AbstractCacheEntry.parse: a " + _file); _file = file; //System.out.println("WodParserCacheEntry.parse: set model (file) = " + model); _setModel(model); if (file != null && file.exists()) { _lastParseTime = file.getModificationStamp(); } _documentChanged = false; } return model; } public synchronized void clear() { // System.out.println("AbstractCacheEntry.clear: " + this); // Exception e= new Exception(); // e.fillInStackTrace(); // e.printStackTrace(System.out); _setModel(null); _lastParseTime = -1; } public synchronized T parse() throws Exception { T model = null; clear(); if (_document != null) { model = parse(_document, true); //System.out.println("WodParserCache.parseHtmlAndWodIfNecessary: ... from document"); } else if (_file != null && _file.exists()) { //System.out.println("WodParserCache.parseHtmlAndWodIfNecessary: ... from file"); model = parse(_file, true); } else if (_contents != null) { model = parse(_contents, true); } else { // System.out.println("AbstractCacheEntry.parse: " + this + " => null"); model = null; _setModel(null); _contents = null; _lastParseTime = -1; _documentChanged = false; _validated = false; getCache()._setValidated(false); } return model; } public synchronized boolean shouldParse() { return _documentChanged || (_file != null && ((_file.exists() && _file.getModificationStamp() != _lastParseTime) || (!_file.exists() && _lastParseTime > 0))); } }