PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/emf-2.8.0/org.eclipse.emf.codegen/src/org/eclipse/emf/codegen/jet/JETCompileTemplateOperation.java

#
Java | 374 lines | 300 code | 39 blank | 35 comment | 53 complexity | a4707abb6531a6b0074a70f7253593b7 MD5 | raw file
  1. /**
  2. * Copyright (c) 2002-2006 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM - Initial API and implementation
  10. */
  11. package org.eclipse.emf.codegen.jet;
  12. import java.io.ByteArrayInputStream;
  13. import java.io.File;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.io.StringWriter;
  17. import java.io.UnsupportedEncodingException;
  18. import java.util.ArrayList;
  19. import java.util.Arrays;
  20. import java.util.Collection;
  21. import java.util.HashSet;
  22. import java.util.List;
  23. import java.util.ListIterator;
  24. import java.util.StringTokenizer;
  25. import org.eclipse.core.resources.IContainer;
  26. import org.eclipse.core.resources.IFile;
  27. import org.eclipse.core.resources.IFolder;
  28. import org.eclipse.core.resources.IProject;
  29. import org.eclipse.core.resources.IResource;
  30. import org.eclipse.core.resources.IWorkspaceRoot;
  31. import org.eclipse.core.resources.IWorkspaceRunnable;
  32. import org.eclipse.core.resources.IncrementalProjectBuilder;
  33. import org.eclipse.core.resources.ResourcesPlugin;
  34. import org.eclipse.core.runtime.CoreException;
  35. import org.eclipse.core.runtime.IPath;
  36. import org.eclipse.core.runtime.IProgressMonitor;
  37. import org.eclipse.core.runtime.IStatus;
  38. import org.eclipse.core.runtime.Path;
  39. import org.eclipse.core.runtime.SubProgressMonitor;
  40. import org.eclipse.emf.codegen.CodeGenPlugin;
  41. import org.eclipse.emf.common.CommonPlugin;
  42. import org.eclipse.emf.common.util.DiagnosticException;
  43. import org.eclipse.emf.common.util.URI;
  44. public class JETCompileTemplateOperation implements IWorkspaceRunnable
  45. {
  46. protected static final String JET_EXTENSION = "jet";
  47. protected IProject project;
  48. protected Collection<?> containers;
  49. protected List<Object> files = new ArrayList<Object>();
  50. protected boolean inBuild;
  51. /**
  52. * Creates an instance given the collection of resources.
  53. */
  54. public JETCompileTemplateOperation(IProject project, Collection<?> containers) throws CoreException
  55. {
  56. this.project = project;
  57. this.containers = containers;
  58. for (Object container : containers)
  59. {
  60. if (container instanceof IContainer)
  61. {
  62. consider((IContainer)container);
  63. }
  64. else
  65. {
  66. consider(container.toString());
  67. }
  68. }
  69. }
  70. /**
  71. * Creates an instance given the collection of resources.
  72. */
  73. public JETCompileTemplateOperation(IProject project, Collection<?> containers, Collection<?> resources) throws CoreException
  74. {
  75. super();
  76. this.project = project;
  77. this.containers = containers;
  78. for (Object object : resources)
  79. {
  80. if (object instanceof IFile)
  81. {
  82. IFile file = (IFile)object;
  83. for (IContainer container = file.getParent(); container != null; container = container.getParent())
  84. {
  85. if (containers.contains(container))
  86. {
  87. consider(file);
  88. break;
  89. }
  90. }
  91. }
  92. else if (object instanceof IContainer)
  93. {
  94. for (IContainer container = (IContainer)object; container != null; container = container.getParent())
  95. {
  96. if (containers.contains(container))
  97. {
  98. consider(container);
  99. break;
  100. }
  101. }
  102. }
  103. }
  104. }
  105. /**
  106. * Returns true if there are files to compile.
  107. */
  108. public boolean shouldCompile()
  109. {
  110. return !files.isEmpty();
  111. }
  112. /**
  113. * Adds the URI.
  114. */
  115. protected void consider(String uri)
  116. {
  117. URI baseURI = URI.createURI(uri);
  118. URI localURI = CommonPlugin.asLocalURI(baseURI);
  119. if (localURI.isFile() && !localURI.isRelative())
  120. {
  121. File file = new File(localURI.toFileString());
  122. if (file.isDirectory() && !uri.endsWith("/"))
  123. {
  124. baseURI = URI.createURI(uri + "/");
  125. }
  126. consider(baseURI, localURI, new File(localURI.toFileString()));
  127. }
  128. }
  129. protected void consider(URI baseURI, URI localURI, File file)
  130. {
  131. if (file.isDirectory())
  132. {
  133. File [] files = file.listFiles();
  134. for (int i = 0; i < files.length; ++i)
  135. {
  136. consider(baseURI, localURI, files[i]);
  137. }
  138. }
  139. else if (file.isFile() && file.getName().endsWith(JET_EXTENSION) && file.getName().indexOf('.') != -1)
  140. {
  141. files.add(URI.createFileURI(file.getAbsolutePath()).deresolve(localURI).resolve(baseURI));
  142. }
  143. }
  144. /**
  145. * Adds the file to {@link #files} the file ends with the {@link #JET_EXTENSION} extension.
  146. */
  147. protected void consider(IFile file)
  148. {
  149. if (file.getFileExtension() != null && file.getFileExtension().endsWith(JET_EXTENSION))
  150. {
  151. files.add(file);
  152. }
  153. }
  154. /**
  155. * Considers all the files of a container and all its subcontainer.
  156. */
  157. protected void consider(IContainer container) throws CoreException
  158. {
  159. IResource[] children = container.members();
  160. if (children != null)
  161. {
  162. for (int i = 0; i < children.length; ++i)
  163. {
  164. IResource resource = children[i];
  165. if (resource instanceof IFile)
  166. {
  167. consider((IFile)resource);
  168. }
  169. else if (resource instanceof IContainer)
  170. {
  171. consider((IContainer)resource);
  172. }
  173. }
  174. }
  175. }
  176. /**
  177. */
  178. public void run(IProgressMonitor progressMonitor) throws CoreException
  179. {
  180. try
  181. {
  182. progressMonitor.beginTask("", 3 * files.size());
  183. progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCompilingTemplates_message"));
  184. IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
  185. Collection<IProject> jetProjects = new HashSet<IProject>();
  186. HashSet<String> visitedRelativePaths = new HashSet<String>();
  187. for (Object file : files)
  188. {
  189. String fileName = file instanceof IFile ? ((IFile)file).getName() : file.toString();
  190. progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETCompile_message", new Object [] { fileName }));
  191. JETNature nature = JETNature.getRuntime(project);
  192. IContainer directory = nature.getJavaSourceContainer();
  193. if(!directory.exists())
  194. {
  195. project.getFolder(directory.getProjectRelativePath()).create(true, true, new SubProgressMonitor(progressMonitor, 1));
  196. }
  197. IPath filePath = file instanceof IFile ? ((IFile)file).getFullPath() : new Path(file.toString());
  198. List<Object> templateContainers = nature.getTemplateContainers();
  199. List<Object> templateSourceContainers = nature.getTemplateSourceContainers();
  200. String [] containerLocations = new String [templateContainers.size()];
  201. for (ListIterator<Object> j = templateContainers.listIterator(); j.hasNext(); )
  202. {
  203. Object container = j.next();
  204. if (container instanceof IContainer)
  205. {
  206. containerLocations[j.previousIndex()] = URI.createPlatformResourceURI(((IContainer)container).getFullPath().toString(), true).toString();
  207. }
  208. else
  209. {
  210. containerLocations[j.previousIndex()] = container.toString();
  211. }
  212. }
  213. for (Object container : templateSourceContainers)
  214. {
  215. IPath containerPath = container instanceof IContainer ? ((IContainer)container).getFullPath() : new Path(container.toString());
  216. if (containerPath.isPrefixOf(filePath))
  217. {
  218. String relativePath = filePath.removeFirstSegments(containerPath.segmentCount()).setDevice(null).toString();
  219. if (visitedRelativePaths.add(relativePath))
  220. {
  221. JETCompiler compiler = new JETCompiler(containerLocations, relativePath);
  222. compiler.parse();
  223. StringWriter stringWriter = new StringWriter();
  224. compiler.generate(stringWriter);
  225. JETSkeleton skeleton = compiler.getSkeleton();
  226. if (skeleton.getClassName().equals(""))
  227. {
  228. skeleton.setClassName(fileName.substring(0, fileName.indexOf('.')));
  229. }
  230. if (skeleton.getPackageName() != null)
  231. {
  232. directory = getPackageContainer(directory, skeleton.getPackageName(), new SubProgressMonitor(progressMonitor, 1));
  233. }
  234. else
  235. {
  236. progressMonitor.worked(1);
  237. }
  238. IFile outputFile =
  239. workspaceRoot.getFile(directory.getFullPath().append(skeleton.getClassName() + ".java"));
  240. progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_JETUpdate_message", new Object [] { fileName }));
  241. String encoding = outputFile.getCharset();
  242. String result = stringWriter.getBuffer().toString();
  243. byte [] bytes;
  244. try
  245. {
  246. bytes = encoding == null ? result.getBytes() : result.getBytes(encoding);
  247. }
  248. catch (UnsupportedEncodingException exception)
  249. {
  250. bytes = result.getBytes();
  251. }
  252. if (!outputFile.exists())
  253. {
  254. outputFile.create(new ByteArrayInputStream(bytes), true, progressMonitor);
  255. }
  256. else
  257. {
  258. boolean changed = true;
  259. try
  260. {
  261. InputStream inputStream = outputFile.getContents();
  262. byte [] oldBytes = new byte[inputStream.available()];
  263. inputStream.read(oldBytes);
  264. inputStream.close();
  265. changed = !Arrays.equals(oldBytes, bytes);
  266. }
  267. catch (IOException exception)
  268. {
  269. // Ignore
  270. }
  271. if (changed)
  272. {
  273. if (outputFile.isReadOnly())
  274. {
  275. // This call should get the files checked out from version control if the project is a 'team' project.
  276. //
  277. IStatus status = ResourcesPlugin.getWorkspace().validateEdit(new IFile [] { outputFile }, null);
  278. if (!status.isOK())
  279. {
  280. throw new CoreException(status);
  281. }
  282. }
  283. outputFile.setContents(new ByteArrayInputStream(bytes), true, true, progressMonitor);
  284. }
  285. }
  286. jetProjects.add(outputFile.getProject());
  287. progressMonitor.worked(1);
  288. break;
  289. }
  290. }
  291. }
  292. }
  293. // Kick of a Java build if not already in a build.
  294. //
  295. if (!isInBuild())
  296. {
  297. for (IProject project : jetProjects)
  298. {
  299. progressMonitor.subTask
  300. (CodeGenPlugin.getPlugin().getString("_UI_JETJavaCompileProject_message", new Object [] { project.getFullPath() }));
  301. project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(progressMonitor, 1));
  302. }
  303. }
  304. }
  305. catch (JETException exception)
  306. {
  307. throw DiagnosticException.toCoreException(exception);
  308. }
  309. finally
  310. {
  311. progressMonitor.done();
  312. }
  313. }
  314. protected IContainer getPackageContainer(IContainer root, String packagename, IProgressMonitor monitor) throws CoreException
  315. {
  316. for (StringTokenizer stringTokenizer = new StringTokenizer(packagename, "."); stringTokenizer.hasMoreTokens(); )
  317. {
  318. IFolder newContainer = root.getFolder(new Path(stringTokenizer.nextToken()));
  319. if (!newContainer.exists())
  320. {
  321. newContainer.create(true, true, monitor);
  322. }
  323. root = newContainer;
  324. }
  325. return root;
  326. }
  327. public boolean isInBuild()
  328. {
  329. return inBuild;
  330. }
  331. public void setInBuild(boolean build)
  332. {
  333. inBuild = build;
  334. }
  335. }