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 }