/*******************************************************************************
* Copyright © 2005, 2013 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.core.internal.binding;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.edt.compiler.internal.core.builder.BuildException;
import org.eclipse.edt.compiler.internal.io.IIOBufferReader;
import org.eclipse.edt.compiler.internal.io.IIOBufferWriter;
import org.eclipse.edt.compiler.internal.io.IRFileNameUtility;
import org.eclipse.edt.ide.core.internal.lookup.ProjectBuildPathManager;
import org.eclipse.edt.ide.core.internal.lookup.ProjectEnvironmentManager;
import org.eclipse.edt.ide.core.internal.lookup.ProjectIREnvironment;
import org.eclipse.edt.mof.egl.Type;
import org.eclipse.edt.mof.serialization.SerializationException;
import org.eclipse.edt.mof.utils.NameUtile;
/**
* @author winghong
*/
public class BinaryFileManager {
public static class Writer implements IIOBufferWriter {
private static final boolean DEBUG = false;
private byte[] entry;
private IFile bufferFile;
public Writer(IFile bufferFile) {
this.bufferFile = bufferFile;
}
public void beginWriting() throws IOException {
entry = null;
}
public void writeEntry(String entryName, Object value) throws IOException, SerializationException {
this.entry = (byte[])value;
}
public void finishWriting() throws IOException {
InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream(entry));
try{
if (bufferFile.exists()) {
// Deal with shared output folders... last one wins... no collision cases detected
if(DEBUG){
System.out.println("Writing changed file " + bufferFile.getName());//$NON-NLS-1$
}
if (entry.length > 0){
bufferFile.setContents(inputStream, true, false, null);
if (!bufferFile.isDerived())
bufferFile.setDerived(true, null);
}else{
bufferFile.delete(true,null);
}
} else if(entry.length > 0){
// Default implementation just writes out the bytes for the new build file...
if(DEBUG){
System.out.println("Writing new file " + bufferFile.getName());//$NON-NLS-1$
}
bufferFile.create(inputStream, IResource.FORCE, null);
bufferFile.setDerived(true, null);
}
}catch(CoreException e){
throw new IOException("EclipseZipFileIOBufferWriter::finishWriting"); //$NON-NLS-1$
}finally{
inputStream.close();
}
}
public void allEntriesRemoved() {
try{
if(DEBUG){
System.out.println("Removing file " + bufferFile.getName());//$NON-NLS-1$
}
if(bufferFile.exists()){
bufferFile.delete(true, false, null);
}
}catch(CoreException e){
throw new BuildException(e);
}
}
}
public static class Reader implements IIOBufferReader {
private IFile bufferFile;
public Reader(IFile bufferFile) {
this.bufferFile = bufferFile;
}
public Object readEntry(String name) throws IOException {
Object result = null;
if(bufferFile.exists()){
BufferedInputStream inputStream;
try{
inputStream = new BufferedInputStream(bufferFile.getContents());
try{
byte[] contents = new byte[inputStream.available()];
inputStream.read(contents);
result = contents;
}finally{
inputStream.close();
}
}catch (CoreException e) {
throw new BuildException("CoreException", e); //$NON-NLS-1$
}
}
return result;
}
public List getEntries() throws IOException {
// Always one entry with the name of the part, which is the name of the file
ArrayList entries = new ArrayList();
if(bufferFile.exists()){
String name =new String(bufferFile.getName());
IPath path = new Path(name);
path = path.removeFileExtension();
entries.add(NameUtile.getAsName(path.toString())); // Intern entry names, which in this case are part names
}
return entries;
}
public InputStream getInputStream(String name)throws IOException{
throw new UnsupportedOperationException();
}
}
private static BinaryFileManager INSTANCE = new BinaryFileManager();
private BinaryFileManager() {
super();
}
public static BinaryFileManager getInstance() {
return INSTANCE;
}
private IFile[] getOutputFileForRead(String packageName, String partName, IProject project){
try{
IContainer output = ProjectBuildPathManager.getInstance().getProjectBuildPath(project).getOutputLocation();
IPath pathWithoutExt = new Path(IRFileNameUtility.toIRFileName(packageName).replace('.', '/')).append(IRFileNameUtility.toIRFileName(partName));
return new IFile[] {
output.getFile(pathWithoutExt.addFileExtension("eglxml")),
output.getFile(pathWithoutExt.addFileExtension("eglbin")),
output.getFile(pathWithoutExt.addFileExtension("mofxml")),
output.getFile(pathWithoutExt.addFileExtension("mofbin"))
};
}catch(Exception e){
throw new BuildException(e);
}
}
public void removePart(String packageName, String name, IProject project){
removePart(packageName, name, project, true);
}
public void removePart(String packageName, String name, IProject project, boolean deleteFromDisk){
if (deleteFromDisk) {
IFile[] files = getOutputFileForRead(packageName, name, project);
// Remove from the disk
for (IFile file : files) {
if (file.exists()) {
Writer writer = new Writer(ResourcesPlugin.getWorkspace().getRoot().getFile(file.getFullPath()));
writer.allEntriesRemoved();
}
}
}
// remove this part from the part cache
ProjectIREnvironment env = ProjectEnvironmentManager.getInstance().getProjectEnvironment(project).getIREnvironment();
env.remove(eglIRKey(packageName, name));
env.remove(mofIRKey(packageName, name));
}
public static String eglIRKey(String packageName, String partName) {
StringBuilder buf = new StringBuilder();
buf.append(Type.EGL_KeyScheme);
buf.append(Type.KeySchemeDelimiter);
if (packageName != null && packageName.length() > 0) {
buf.append(packageName);
buf.append('.');
}
buf.append(partName);
return buf.toString();
}
public static String mofIRKey(String packageName, String partName) {
StringBuilder buf = new StringBuilder();
if (packageName != null && packageName.length() > 0) {
buf.append(packageName);
buf.append('.');
}
buf.append(partName);
return buf.toString();
}
public void addPackage(String packages,IProject project){
IContainer container = ProjectBuildPathManager.getInstance().getProjectBuildPath(project).getOutputLocation();
try {
org.eclipse.edt.ide.core.internal.builder.Util.createFolder(new Path(IRFileNameUtility.toIRFileName(packages).replace('.', '/')),container);
} catch (CoreException e) {
throw new BuildException(e);
}
}
public void removePackage(String packages,IProject project){
IContainer container = ProjectBuildPathManager.getInstance().getProjectBuildPath(project).getOutputLocation();
container = container.getFolder(new Path(IRFileNameUtility.toIRFileName(packages).replace('.', '/')));
if (container.exists() && container.getType() != IResource.PROJECT){ // if somehow using the project root, don't delete it
try {
container.delete(true,null);
} catch (CoreException e) {
throw new BuildException(e);
}
}
}
}