blob: b6acde881835a07231d5bd8147688028638b46c6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2009 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* wharley@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.apt.pluggable.core.filer;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.apt.core.internal.env.BinaryFileOutputStream;
import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil;
import org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin;
import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeProcessingEnvImpl;
/**
* @see BinaryFileOutputStream
*/
public class IdeNonSourceOutputStream extends ByteArrayOutputStream
{
private final IdeProcessingEnvImpl _env;
private final IFile _file;
private final Collection<IFile> _parentFiles;
public IdeNonSourceOutputStream(IdeProcessingEnvImpl env, IFile file, Collection<IFile> parentFiles) {
_env = env;
_file = file;
_parentFiles = parentFiles;
}
@Override
public void close() throws IOException {
super.close();
InputStream contents = new ByteArrayInputStream(toByteArray());
try {
boolean contentsChanged = true;
if (!_file.exists()) {
saveToDisk(contents, true);
}
else {
InputStream in = null;
InputStream oldData = null;
try {
// Only write the contents if the data is different
in = new ByteArrayInputStream(toByteArray());
oldData = new BufferedInputStream(_file.getContents());
if (FileSystemUtil.compareStreams(in, oldData)) {
contentsChanged = false;
}
}
catch (CoreException ce) {
// Ignore -- couldn't read the old data, so assume it's different
contentsChanged = true;
}
finally {
closeInputStream(in);
closeInputStream(oldData);
}
if (contentsChanged) {
contents.reset();
saveToDisk(contents, false);
}
}
}
finally {
closeInputStream(contents);
}
// If there are no parents, we don't need to track dependencies
if (_parentFiles != null && !_parentFiles.isEmpty()) {
_env.getAptProject().getGeneratedFileManager().addGeneratedFileDependency(_parentFiles, _file);
_env.addNewResource(_file);
}
}
private void closeInputStream(InputStream stream) {
if (stream != null) {
try {
stream.close();
}
catch (IOException ioe) {}
}
}
private void saveToDisk(InputStream toSave, boolean create) throws IOException{
try {
FileSystemUtil.makeDerivedParentFolders(_file.getParent());
if (create) {
_file.create(toSave, IResource.FORCE | IResource.DERIVED, null);
}
else {
_file.setContents(toSave, true, false, null);
}
}
catch (CoreException ce) {
if (_file.exists()) {
// Do nothing. This is a case-insensitive file system mismatch,
// and the underlying platform has saved the contents already.
}
else {
Apt6Plugin.log(ce, "Could not create generated non-Java file " + _file.getName()); //$NON-NLS-1$
throw new IOException(ce);
}
}
}
}