001 package org.meta_environment.eclipse.files; 002 003 import java.io.ByteArrayInputStream; 004 import java.io.File; 005 006 import org.eclipse.core.resources.IFile; 007 import org.eclipse.core.resources.IFolder; 008 import org.eclipse.core.resources.IProject; 009 import org.eclipse.core.resources.IResource; 010 import org.eclipse.core.resources.IResourceChangeEvent; 011 import org.eclipse.core.resources.IResourceChangeListener; 012 import org.eclipse.core.resources.IResourceDelta; 013 import org.eclipse.core.resources.IResourceDeltaVisitor; 014 import org.eclipse.core.resources.ResourcesPlugin; 015 import org.eclipse.core.runtime.CoreException; 016 import org.eclipse.core.runtime.IPath; 017 import org.eclipse.core.runtime.NullProgressMonitor; 018 import org.eclipse.core.runtime.Path; 019 import org.eclipse.imp.language.Language; 020 import org.eclipse.imp.language.LanguageRegistry; 021 import org.eclipse.imp.runtime.RuntimePlugin; 022 023 import toolbus.adapter.eclipse.EclipseTool; 024 import aterm.ATerm; 025 import aterm.pure.binary.BinaryWriter; 026 027 public class ResourceChanges extends EclipseTool implements IResourceChangeListener { 028 private static final String BIN_FOLDER = "bin"; 029 private static final String EXTENSION_SEPARATOR = "."; 030 031 private static class InstanceKeeper { 032 private static ResourceChanges sInstance = new ResourceChanges(); 033 static{ 034 sInstance.connect(); 035 } 036 } 037 038 private ResourceChanges() { 039 super("resource-changes"); 040 ResourcesPlugin.getWorkspace().addResourceChangeListener(this); 041 } 042 043 static public ResourceChanges getInstance() { 044 return InstanceKeeper.sInstance; 045 } 046 047 public void resourceChanged(IResourceChangeEvent event) { 048 IResourceDelta[] deltas = event.getDelta().getAffectedChildren(); 049 050 try { 051 for (IResourceDelta d : deltas) { 052 053 d.accept(new IResourceDeltaVisitor() { 054 public boolean visit(IResourceDelta delta) 055 throws CoreException { 056 IResource resource = delta.getResource(); 057 058 if (resource instanceof IFile) { 059 IPath path = resource.getLocation(); 060 061 Language l = LanguageRegistry.findLanguage(path, 062 null); 063 064 if (l != null) { 065 switch (delta.getKind()) { 066 case IResourceDelta.OPEN: 067 fileCreated(l, resource); 068 break; 069 case IResourceDelta.ADDED: 070 fileCreated(l, resource); 071 break; 072 case IResourceDelta.CHANGED: 073 if ((delta.getFlags() & IResourceDelta.CONTENT) != 0) { 074 fileChanged(l, resource); 075 } 076 break; 077 case IResourceDelta.REMOVED: 078 fileRemovedEvent(l, resource); 079 break; 080 } 081 } 082 return false; 083 } 084 return true; 085 } 086 }); 087 088 } 089 } catch (CoreException e) { 090 e.printStackTrace(); 091 } 092 } 093 094 private void fileCreated(Language l, IResource resource) { 095 096 if (l != null && !resource.isDerived() && resource.isAccessible()) { 097 sendEvent(factory.make("create-module(<str>,<str>)", l.getName(), 098 resource.getLocation().toOSString())); 099 } 100 } 101 102 private void fileRemovedEvent(Language l, IResource resource) { 103 if (l != null) { 104 sendEvent(factory.make("delete-module(<str>,<str>)", l.getName(), 105 resource.getLocation().toOSString())); 106 } 107 108 } 109 110 private void fileChanged(Language l, IResource resource) { 111 if (l != null) { 112 sendEvent(factory.make("build-module(<str>,<str>)", l.getName(), 113 resource.getLocation().toOSString() 114 )); 115 } 116 } 117 118 public void saveBuild(String sourcePathStr, String targetExt, String content) { 119 try { 120 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 121 122 if (targetFile != null) { 123 if (targetFile.exists()) { 124 targetFile.setContents(new ByteArrayInputStream(content.getBytes()), 125 IResource.FORCE, 126 new NullProgressMonitor()); 127 } 128 else { 129 targetFile.create(new ByteArrayInputStream(content.getBytes()), IResource.FORCE, 130 new NullProgressMonitor()); 131 } 132 133 targetFile.setDerived(true); 134 } 135 } 136 catch (CoreException e) { 137 RuntimePlugin.getInstance().logException("could not save build for " + sourcePathStr, e); 138 } 139 catch (Exception e) { 140 RuntimePlugin.getInstance().logException("could not save build for " + sourcePathStr, e); 141 } 142 } 143 144 public void saveBuild(String sourcePathStr, String targetExt, ATerm content) { 145 try { 146 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 147 148 if (targetFile != null) { 149 150 BinaryWriter.writeTermToSAFFile(decode(content), new File(targetFile.getLocation().toOSString())); 151 152 targetFile.refreshLocal(0, new NullProgressMonitor()); 153 targetFile.setDerived(true); 154 } 155 } 156 catch (CoreException e) { 157 RuntimePlugin.getInstance().logException("could not save build for " + sourcePathStr, e); 158 } 159 catch (Exception e) { 160 RuntimePlugin.getInstance().logException("could not save build for " + sourcePathStr, e); 161 } 162 } 163 164 public void cleanBuild(String sourcePathStr, String targetExt) { 165 166 try { 167 IFile targetFile = getTargetFile(sourcePathStr, targetExt); 168 169 if (targetFile != null && targetFile.exists()) { 170 targetFile.delete(true, false, new NullProgressMonitor()); 171 System.err.println("Resources: cleaned " + targetFile); 172 } 173 } catch (CoreException e) { 174 RuntimePlugin.getInstance().logException("could not clean build for " + sourcePathStr, e); 175 } 176 } 177 178 private IFile getTargetFile(String sourcePathStr, String targetExt) 179 throws CoreException { 180 IFile sourceFile = getFile(sourcePathStr); 181 182 while (targetExt.startsWith(EXTENSION_SEPARATOR)) { 183 targetExt = targetExt.substring(1); 184 } 185 186 if (sourceFile != null) { 187 IProject project = sourceFile.getProject(); 188 IPath sourcePath = sourceFile.getProjectRelativePath(); 189 IFolder binFolder = project.getFolder(BIN_FOLDER); 190 IPath targetPath = binFolder.getProjectRelativePath().append(sourcePath.removeFileExtension() 191 .addFileExtension(targetExt)); 192 193 IPath current = Path.ROOT; 194 for (String segment : targetPath.removeLastSegments(1).segments()) { 195 current = current.append(segment); 196 IFolder path = project.getFolder(current); 197 if (!path.exists()) { 198 path.create(true, true, null); 199 } 200 } 201 202 IFile targetFile = sourceFile.getProject().getFile(targetPath); 203 204 return targetFile; 205 } 206 207 return null; 208 } 209 210 private IFile getFile(String source) { 211 return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(source)); 212 } 213 }