001 package org.meta_environment.eclipse.files; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.File; 005 import java.io.IOException; 006 007 import org.eclipse.core.resources.IFile; 008 import org.eclipse.core.resources.IFolder; 009 import org.eclipse.core.resources.IProject; 010 import org.eclipse.core.resources.IResource; 011 import org.eclipse.core.resources.ResourcesPlugin; 012 import org.eclipse.core.runtime.CoreException; 013 import org.eclipse.core.runtime.IPath; 014 import org.eclipse.core.runtime.NullProgressMonitor; 015 import org.eclipse.core.runtime.Path; 016 import org.eclipse.imp.runtime.RuntimePlugin; 017 import org.eclipse.imp.utils.StreamUtils; 018 019 import toolbus.adapter.eclipse.EclipseTool; 020 import aterm.ATerm; 021 import aterm.pure.binary.BinaryWriter; 022 023 public class BuildResults extends EclipseTool { 024 private static final String BIN_FOLDER = "bin"; 025 private static final String EXTENSION_SEPARATOR = "."; 026 027 private static class InstanceKeeper { 028 private static BuildResults sInstance = new BuildResults(); 029 static { 030 sInstance.connect(); 031 } 032 } 033 034 private BuildResults() { 035 super("build-results"); 036 } 037 038 static public BuildResults getInstance() { 039 return InstanceKeeper.sInstance; 040 } 041 042 public void saveBuild(String sourcePathStr, String targetExt, String content) { 043 try { 044 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 045 046 if (targetFile != null) { 047 if (targetFile.exists()) { 048 targetFile.setContents(new ByteArrayInputStream(content 049 .getBytes()), IResource.FORCE, 050 new NullProgressMonitor()); 051 } else { 052 targetFile.create(new ByteArrayInputStream(content 053 .getBytes()), IResource.FORCE, 054 new NullProgressMonitor()); 055 } 056 057 targetFile.setDerived(true); 058 } 059 } catch (CoreException e) { 060 RuntimePlugin.getInstance().logException( 061 "could not save build for " + sourcePathStr, e); 062 } catch (Exception e) { 063 RuntimePlugin.getInstance().logException( 064 "could not save build for " + sourcePathStr, e); 065 } 066 } 067 068 public void saveBuild(String sourcePathStr, String targetExt, ATerm content) { 069 try { 070 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 071 072 if (targetFile != null) { 073 074 BinaryWriter.writeTermToSAFFile(decode(content), new File( 075 targetFile.getLocation().toOSString())); 076 077 targetFile.refreshLocal(0, new NullProgressMonitor()); 078 targetFile.setDerived(true); 079 } 080 } catch (CoreException e) { 081 RuntimePlugin.getInstance().logException( 082 "could not save build for " + sourcePathStr, e); 083 } catch (Exception e) { 084 RuntimePlugin.getInstance().logException( 085 "could not save build for " + sourcePathStr, e); 086 } 087 } 088 089 public void cleanBuild(String sourcePathStr, String targetExt) { 090 091 try { 092 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 093 094 if (targetFile != null && targetFile.exists()) { 095 targetFile.delete(true, false, new NullProgressMonitor()); 096 System.err.println("Resources: cleaned " + targetFile); 097 } 098 } catch (CoreException e) { 099 RuntimePlugin.getInstance().logException( 100 "could not clean build for " + sourcePathStr, e); 101 } 102 } 103 104 public ATerm loadBuild(String sourcePathStr, String targetExt) { 105 try { 106 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 107 108 if (targetFile != null && targetFile.exists()) { 109 ATerm build = getFactory().readFromFile( 110 targetFile.getLocation().toOSString()); 111 112 return getFactory().make("build(<term>)", build); 113 } 114 } catch (CoreException e) { 115 RuntimePlugin.getInstance().logException( 116 "could not get build for " + sourcePathStr, e); 117 } catch (IOException e) { 118 RuntimePlugin.getInstance().logException( 119 "could not get build for " + sourcePathStr, e); 120 } 121 122 return getFactory().make("build(undefined)"); 123 } 124 125 public ATerm loadStrBuild(String sourcePathStr, String targetExt) { 126 try { 127 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 128 129 if (targetFile != null && targetFile.exists()) { 130 String content = StreamUtils.readStreamContents(targetFile 131 .getContents()); 132 return getFactory().make("build(<str>)", content); 133 } 134 } catch (CoreException e) { 135 RuntimePlugin.getInstance().logException( 136 "could not get build for " + sourcePathStr, e); 137 } 138 139 return getFactory().make("build(\"***build-not-found***\")"); 140 } 141 142 private IFile getTargetFile(String sourcePathStr, String targetExt) 143 throws CoreException { 144 IFile sourceFile = getFile(sourcePathStr); 145 146 while (targetExt.startsWith(EXTENSION_SEPARATOR)) { 147 targetExt = targetExt.substring(1); 148 } 149 150 if (sourceFile != null) { 151 return createTargetFile(targetExt, sourceFile); 152 } 153 return createLibraryTargetFile(sourcePathStr, targetExt); 154 } 155 156 private IFile createTargetFile(String targetExt, IFile sourceFile) 157 throws CoreException { 158 IProject project; 159 IPath targetPath; 160 project = sourceFile.getProject(); 161 IFolder binFolder = project.getFolder(BIN_FOLDER); 162 163 IPath sourcePath = sourceFile.getProjectRelativePath(); 164 targetPath = binFolder.getProjectRelativePath().append( 165 sourcePath.removeFileExtension().addFileExtension(targetExt)); 166 167 return createFile(project, targetPath); 168 } 169 170 /** 171 * Workaround for not having a feature for libraries. As a heuristic, 172 * we recognize libraries if they are in a "library" subdir and store 173 * the build results in "tmp" project. 174 * 175 * TODO remove this code and have an implementation of a search path with jars 176 */ 177 private IFile createLibraryTargetFile(String sourcePathStr, String targetExt) 178 throws CoreException { 179 IProject project; 180 IPath targetPath; 181 182 project = ResourcesPlugin.getWorkspace().getRoot().getProject("tmp"); 183 if (!project.exists()) { 184 project.create(null); 185 } 186 else if (!project.isOpen()) { 187 project.open(null); 188 } 189 190 IFolder binFolder = project.getFolder(BIN_FOLDER); 191 192 int libIndex = sourcePathStr.indexOf(File.separator + "library"); 193 if (libIndex != -1) { 194 sourcePathStr = sourcePathStr.substring(libIndex + "library".length() + 1); 195 196 targetPath = binFolder.getProjectRelativePath().append(sourcePathStr).removeFileExtension().addFileExtension(targetExt); 197 198 return createFile(project, targetPath); 199 } 200 201 return null; 202 } 203 204 private IFile createFile(IProject project, IPath targetPath) 205 throws CoreException { 206 IPath current = Path.ROOT; 207 for (String segment : targetPath.removeLastSegments(1).segments()) { 208 current = current.append(segment); 209 IFolder path = project.getFolder(current); 210 if (!path.exists()) { 211 path.create(true, true, null); 212 } 213 } 214 215 IFile targetFile = project.getFile(targetPath); 216 return targetFile; 217 } 218 219 private IFile getFile(String source) { 220 return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation( 221 new Path(source)); 222 } 223 }