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;
}
}
}