package jetbrains.mps.internal.make.runtime.java; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.util.List; import org.jetbrains.mps.openapi.model.SModel; import java.util.ArrayList; import jetbrains.mps.vfs.IFile; import org.jdom.Element; import java.util.Collection; import jetbrains.mps.generator.ModelGenerationStatusManager; import java.io.OutputStreamWriter; import java.io.BufferedOutputStream; import jetbrains.mps.util.FileUtil; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.InputStream; import java.util.Arrays; import org.jdom.Document; import jetbrains.mps.util.JDOMUtil; public class FileProcessor { private static final Logger LOG = LogManager.getLogger(FileProcessor.class); private final List<SModel> myModels = new ArrayList<SModel>(); private final List<FileProcessor.FileAndContent> myFilesAndContents = new ArrayList<FileProcessor.FileAndContent>(); private final List<IFile> myFilesToDelete = new ArrayList<IFile>(); private final Object LOCK = new Object(); public FileProcessor() { } public void invalidateModel(SModel modelDescriptor) { synchronized (LOCK) { myModels.add(modelDescriptor); } } public boolean saveContent(IFile file, String content) { return saveContent(new FileProcessor.FileAndContent(file, new FileProcessor.StringFileContent(content))); } public boolean saveContent(IFile file, Element content) { return saveContent(new FileProcessor.FileAndContent(file, new FileProcessor.XMLFileContent(content))); } public boolean saveContent(IFile file, byte[] content) { return saveContent(new FileProcessor.FileAndContent(file, new FileProcessor.BinaryFileContent(content))); } private boolean saveContent(FileProcessor.FileAndContent fileAndContent) { myFilesAndContents.add(fileAndContent); return !(fileAndContent.myContent.isUnchanged(fileAndContent.myFile)); } public void filesToDelete(Collection<IFile> files) { myFilesToDelete.addAll(files); } public void flushChanges() { for (FileProcessor.FileAndContent fileAndContent : myFilesAndContents) { fileAndContent.save(); } for (IFile file : myFilesToDelete) { file.delete(); } ModelGenerationStatusManager.getInstance().invalidateData(myModels); } /*package*/ int calcApproximateSize() { int size = 0; for (FileProcessor.FileAndContent fileAndContent : myFilesAndContents) { size += fileAndContent.myContent.calcApproximateSize(); } return size; } private static class FileAndContent { private IFile myFile; private FileProcessor.FileContent myContent; private FileAndContent(IFile file, FileProcessor.FileContent content) { myFile = file; myContent = content; } private void save() { myContent.saveToFile(myFile); } @Override public String toString() { return myFile.toString(); } } private interface FileContent { boolean isUnchanged(IFile file); void saveToFile(IFile file); int calcApproximateSize(); } private static class StringFileContent implements FileProcessor.FileContent { private String myContent; private StringFileContent(String content) { myContent = content; } @Override public void saveToFile(IFile file) { OutputStreamWriter writer = null; try { writer = new OutputStreamWriter(new BufferedOutputStream(file.openOutputStream()), FileUtil.DEFAULT_CHARSET); writer.write(myContent); } catch (IOException e) { FileProcessor.LOG.error((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), e); } finally { if (writer != null) { try { writer.close(); } catch (IOException ignored) { } } } } @Override public boolean isUnchanged(IFile file) { if (!(file.exists())) { return false; } BufferedReader reader = null; StringBuilder res = new StringBuilder(); try { reader = new BufferedReader(new InputStreamReader(file.openInputStream(), FileUtil.DEFAULT_CHARSET)); String line; while ((line = reader.readLine()) != null) { res.append(line).append('\n'); } return res.toString().equals(myContent); } catch (IOException ex) { return false; } finally { try { if (reader != null) { reader.close(); } } catch (IOException ex) { return false; } } } @Override public int calcApproximateSize() { return myContent.getBytes().length; } } private static class BinaryFileContent implements FileProcessor.FileContent { private byte[] myContent; private BinaryFileContent(byte[] content) { myContent = content; } @Override public void saveToFile(IFile file) { OutputStream stream = null; try { stream = file.openOutputStream(); stream.write(myContent); } catch (IOException e) { FileProcessor.LOG.error((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), e); } finally { if (stream != null) { try { stream.close(); } catch (IOException ignored) { } } } } @Override public boolean isUnchanged(IFile file) { if (!(file.exists())) { return false; } long len = file.length(); if (len != myContent.length) { return false; } byte[] res = new byte[myContent.length]; InputStream stream = null; try { stream = file.openInputStream(); if (stream.read(res) != len) { return false; } return Arrays.equals(res, myContent); } catch (IOException ex) { return false; } finally { if (stream != null) { try { stream.close(); } catch (IOException ex) { return false; } } } } @Override public int calcApproximateSize() { return myContent.length; } } private static class XMLFileContent implements FileProcessor.FileContent { private final Document myDocument; private XMLFileContent(Element element) { // if element is right under a document, use this document, otherwise create a new one if (element.getDocument() != null) { assert element.isRootElement() : "Need a document to serialize an xml element; could not save if element is already inside a document"; myDocument = element.getDocument(); } else { myDocument = new Document(element); } } @Override public void saveToFile(IFile file) { try { JDOMUtil.writeDocument(myDocument, file); } catch (IOException e) { FileProcessor.LOG.error((e.getMessage() == null ? e.getClass().getName() : e.getMessage()), e); } } @Override public int calcApproximateSize() { try { return JDOMUtil.printDocument(myDocument).length; } catch (Exception e) { throw new RuntimeException(e); } } @Override public boolean isUnchanged(IFile file) { return false; } } }