1 17 package org.eclipse.emf.codegen.jet; 18 19 20 import java.io.ByteArrayInputStream ; 21 import java.io.ByteArrayOutputStream ; 22 import java.io.File ; 23 import java.io.InputStream ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import java.net.URL ; 28 import java.net.URLClassLoader ; 29 import java.util.ArrayList ; 30 import java.util.List ; 31 import java.util.StringTokenizer ; 32 33 import javax.xml.parsers.DocumentBuilder ; 34 import javax.xml.parsers.DocumentBuilderFactory ; 35 36 import org.osgi.framework.Bundle; 37 import org.w3c.dom.Document ; 38 import org.w3c.dom.Element ; 39 import org.w3c.dom.Node ; 40 import org.xml.sax.InputSource ; 41 42 import org.eclipse.core.resources.IContainer; 43 import org.eclipse.core.resources.IFile; 44 import org.eclipse.core.resources.IFolder; 45 import org.eclipse.core.resources.IMarker; 46 import org.eclipse.core.resources.IProject; 47 import org.eclipse.core.resources.IProjectDescription; 48 import org.eclipse.core.resources.IResource; 49 import org.eclipse.core.resources.IWorkspace; 50 import org.eclipse.core.resources.IncrementalProjectBuilder; 51 import org.eclipse.core.resources.ResourcesPlugin; 52 import org.eclipse.core.runtime.CoreException; 53 import org.eclipse.core.runtime.IPath; 54 import org.eclipse.core.runtime.IProgressMonitor; 55 import org.eclipse.core.runtime.NullProgressMonitor; 56 import org.eclipse.core.runtime.Path; 57 import org.eclipse.core.runtime.Platform; 58 import org.eclipse.core.runtime.SubProgressMonitor; 59 import org.eclipse.jdt.core.IClasspathEntry; 60 import org.eclipse.jdt.core.IJavaModel; 61 import org.eclipse.jdt.core.IJavaProject; 62 import org.eclipse.jdt.core.IPackageFragmentRoot; 63 import org.eclipse.jdt.core.JavaCore; 64 import org.eclipse.jdt.launching.JavaRuntime; 65 66 import org.eclipse.emf.codegen.CodeGenPlugin; 67 import org.eclipse.emf.codegen.util.CodeGenUtil; 68 import org.eclipse.emf.common.CommonPlugin; 69 import org.eclipse.emf.common.util.URI; 70 71 72 75 public class JETEmitter 76 { 77 protected String projectName = ".JETEmitters"; 78 protected Method method; 79 protected Object object; 80 protected String [] templateURIPath; 81 protected String templateURI; 82 protected ClassLoader classLoader; 83 protected String encoding; 84 protected List classpathEntries = new ArrayList (); 85 86 90 public JETEmitter(String templateURI) 91 { 92 this.templateURI = templateURI; 93 this.classLoader = JETEmitter.this.getClass().getClassLoader(); 94 } 95 96 102 public JETEmitter(String [] templateURIPath, String relativeTemplateURI) 103 { 104 this.templateURIPath = templateURIPath; 105 this.templateURI = relativeTemplateURI; 106 this.classLoader = JETEmitter.this.getClass().getClassLoader(); 107 } 108 109 114 public JETEmitter(String templateURI, ClassLoader classLoader) 115 { 116 this.templateURI = templateURI; 117 this.classLoader = classLoader; 118 } 119 120 127 public JETEmitter(String [] templateURIPath, String relativeTemplateURI, ClassLoader classLoader) 128 { 129 this.templateURIPath = templateURIPath; 130 this.templateURI = relativeTemplateURI; 131 this.classLoader = classLoader; 132 } 133 134 142 public JETEmitter(String [] templateURIPath, String relativeTemplateURI, ClassLoader classLoader, String encoding) 143 { 144 this.templateURIPath = templateURIPath; 145 this.templateURI = relativeTemplateURI; 146 this.classLoader = classLoader; 147 this.encoding = encoding; 148 } 149 150 154 public String getProjectName() 155 { 156 return projectName; 157 } 158 159 163 public void setProjectName(String projectName) 164 { 165 this.projectName = projectName; 166 } 167 168 177 public List getClasspathEntries() 178 { 179 return classpathEntries; 180 } 181 182 186 public Object getObject() 187 { 188 return object; 189 } 190 191 195 public void setObject(Object object) 196 { 197 this.object = object; 198 } 199 200 204 public Method getMethod() 205 { 206 return method; 207 } 208 209 213 public void setMethod(Method method) 214 { 215 this.method = method; 216 if ((method.getModifiers() & Modifier.STATIC) == 0 && object == null) 217 { 218 try 219 { 220 object = method.getDeclaringClass().newInstance(); 221 } 222 catch (IllegalAccessException exception) 223 { 224 exception.printStackTrace(); 225 } 226 catch (InstantiationException exception) 227 { 228 exception.printStackTrace(); 229 } 230 } 231 } 232 233 protected class MyJETCompiler extends JETCompiler 234 { 235 public MyJETCompiler(String templateURI) throws JETException 236 { 237 super(templateURI); 238 } 239 240 public MyJETCompiler(String templateURI, String encoding) throws JETException 241 { 242 super(templateURI, encoding); 243 } 244 245 public MyJETCompiler(String [] templateURIPath, String relativeTemplateURI) throws JETException 246 { 247 super(templateURIPath, relativeTemplateURI); 248 } 249 250 public MyJETCompiler(String [] templateURIPath, String relativeTemplateURI, String encoding) throws JETException 251 { 252 super(templateURIPath, relativeTemplateURI, encoding); 253 } 254 255 protected void handleNewSkeleton() 256 { 257 String packageName = skeleton.getPackageName(); 258 String skeletonClassName = skeleton.getClassName(); 259 String qualifiedSkeletonClassName = (packageName.length() == 0 ? "" : packageName + ".") + skeletonClassName; 260 261 try 262 { 263 Class theClass = classLoader.loadClass(qualifiedSkeletonClassName); 264 if (theClass != null) 265 { 266 skeleton.setClassName(skeletonClassName += "_"); 267 } 268 } 269 catch (Exception exception) 270 { 271 } 272 } 273 } 274 275 279 public void initialize(IProgressMonitor progressMonitor) throws JETException 280 { 281 progressMonitor.beginTask("", 10); 282 progressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_GeneratingJETEmitterFor_message", new Object [] { templateURI })); 283 284 try 285 { 286 try 289 { 290 JavaRuntime.getDefaultVMInstall(); 291 } 292 catch (Throwable throwable) 293 { 294 URL jreURL = Platform.getBundle("org.eclipse.emf.codegen").getEntry("plugin.xml"); 297 IPath jrePath = new Path(Platform.asLocalURL(jreURL).getFile()); 298 jrePath = jrePath.removeLastSegments(1).append(new Path("../../jre/lib/rt.jar")); 299 if (!jrePath.equals(JavaCore.getClasspathVariable(JavaRuntime.JRELIB_VARIABLE))) 300 { 301 JavaCore.setClasspathVariable(JavaRuntime.JRELIB_VARIABLE, jrePath, null); 302 } 303 } 304 305 final JETCompiler jetCompiler = 306 templateURIPath == null ? 307 new MyJETCompiler(templateURI, encoding) : 308 new MyJETCompiler(templateURIPath, templateURI, encoding); 309 310 progressMonitor.subTask 311 (CodeGenPlugin.getPlugin().getString("_UI_JETParsing_message", new Object [] { jetCompiler.getResolvedTemplateURI() })); 312 jetCompiler.parse(); 313 progressMonitor.worked(1); 314 315 ByteArrayOutputStream outputStream = new ByteArrayOutputStream (); 316 jetCompiler.generate(outputStream); 317 final InputStream contents = new ByteArrayInputStream (outputStream.toByteArray()); 318 319 final IWorkspace workspace = ResourcesPlugin.getWorkspace(); 320 IJavaModel javaModel= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); 321 if (!javaModel.isOpen()) 322 { 323 javaModel.open(new SubProgressMonitor(progressMonitor, 1)); 324 } 325 else 326 { 327 progressMonitor.worked(1); 328 } 329 330 final IProject project = workspace.getRoot().getProject(getProjectName()); 331 progressMonitor.subTask 332 (CodeGenPlugin.getPlugin().getString("_UI_JETPreparingProject_message", new Object [] { project.getName() })); 333 334 IJavaProject javaProject; 335 if (!project.exists()) 336 { 337 progressMonitor.subTask("JET creating project " + project.getName()); 338 project.create(new SubProgressMonitor(progressMonitor, 1)); 339 progressMonitor.subTask 340 (CodeGenPlugin.getPlugin().getString("_UI_JETCreatingProject_message", new Object [] { project.getName() })); 341 IProjectDescription description = workspace.newProjectDescription(project.getName()); 342 description.setNatureIds(new String [] { JavaCore.NATURE_ID }); 343 description.setLocation(null); 344 project.open(new SubProgressMonitor(progressMonitor, 1)); 345 project.setDescription(description, new SubProgressMonitor(progressMonitor, 1)); 346 } 347 else 348 { 349 project.open(new SubProgressMonitor(progressMonitor, 5)); 350 IProjectDescription description = project.getDescription(); 351 description.setNatureIds(new String [] { JavaCore.NATURE_ID }); 352 project.setDescription(description, new SubProgressMonitor(progressMonitor, 1)); 353 } 354 355 javaProject = JavaCore.create(project); 356 357 progressMonitor.subTask 358 (CodeGenPlugin.getPlugin().getString("_UI_JETInitializingProject_message", new Object [] { project.getName() })); 359 IClasspathEntry classpathEntry = 360 JavaCore.newSourceEntry(new Path("/" + project.getName() + "/src")); 361 362 IClasspathEntry jreClasspathEntry = 363 JavaCore.newVariableEntry 364 (new Path(JavaRuntime.JRELIB_VARIABLE), 365 new Path(JavaRuntime.JRESRC_VARIABLE), 366 new Path(JavaRuntime.JRESRCROOT_VARIABLE)); 367 368 List classpath = new ArrayList (); 369 classpath.add(classpathEntry); 370 classpath.add(jreClasspathEntry); 371 classpath.addAll(classpathEntries); 372 373 IFolder sourceFolder = project.getFolder(new Path("src")); 374 if (!sourceFolder.exists()) 375 { 376 sourceFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1)); 377 } 378 IFolder runtimeFolder = project.getFolder(new Path("runtime")); 379 if (!runtimeFolder.exists()) 380 { 381 runtimeFolder.create(false, true, new SubProgressMonitor(progressMonitor, 1)); 382 } 383 384 IClasspathEntry [] classpathEntryArray = (IClasspathEntry[])classpath.toArray(new IClasspathEntry [classpath.size()]); 385 386 javaProject.setRawClasspath(classpathEntryArray, new SubProgressMonitor(progressMonitor, 1)); 387 388 javaProject.setOutputLocation(new Path("/" + project.getName() + "/runtime"), new SubProgressMonitor(progressMonitor, 1)); 389 390 javaProject.close(); 391 392 progressMonitor.subTask 393 (CodeGenPlugin.getPlugin().getString("_UI_JETOpeningJavaProject_message", new Object [] { project.getName() })); 394 javaProject.open(new SubProgressMonitor(progressMonitor, 1)); 395 396 IPackageFragmentRoot [] packageFragmentRoots = javaProject.getPackageFragmentRoots(); 397 IPackageFragmentRoot sourcePackageFragmentRoot = null; 398 for (int j = 0; j < packageFragmentRoots.length; ++j) 399 { 400 IPackageFragmentRoot packageFragmentRoot = packageFragmentRoots[j]; 401 if (packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) 402 { 403 sourcePackageFragmentRoot = packageFragmentRoot; 404 break; 405 } 406 } 407 408 String packageName = jetCompiler.getSkeleton().getPackageName(); 409 StringTokenizer stringTokenizer = new StringTokenizer (packageName, "."); 410 IProgressMonitor subProgressMonitor = new SubProgressMonitor(progressMonitor, 1); 411 subProgressMonitor.beginTask("", stringTokenizer.countTokens() + 4); 412 subProgressMonitor.subTask(CodeGenPlugin.getPlugin().getString("_UI_CreateTargetFile_message")); 413 IContainer sourceContainer = (IContainer)sourcePackageFragmentRoot.getCorrespondingResource(); 414 while (stringTokenizer.hasMoreElements()) 415 { 416 String folderName = stringTokenizer.nextToken(); 417 sourceContainer = sourceContainer.getFolder(new Path(folderName)); 418 if (!sourceContainer.exists()) 419 { 420 ((IFolder)sourceContainer).create(false, true, new SubProgressMonitor(subProgressMonitor, 1)); 421 } 422 } 423 IFile targetFile = sourceContainer.getFile(new Path(jetCompiler.getSkeleton().getClassName() + ".java")); 424 if (!targetFile.exists()) 425 { 426 subProgressMonitor.subTask 427 (CodeGenPlugin.getPlugin().getString("_UI_JETCreating_message", new Object [] { targetFile.getFullPath() })); 428 targetFile.create(contents, true, new SubProgressMonitor(subProgressMonitor, 1)); 429 } 430 else 431 { 432 subProgressMonitor.subTask 433 (CodeGenPlugin.getPlugin().getString("_UI_JETUpdating_message", new Object [] { targetFile.getFullPath() })); 434 targetFile.setContents(contents, true, true, new SubProgressMonitor(subProgressMonitor, 1)); 435 } 436 437 subProgressMonitor.subTask 438 (CodeGenPlugin.getPlugin().getString("_UI_JETBuilding_message", new Object [] { project.getName() })); 439 project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(subProgressMonitor, 1)); 440 441 IMarker [] markers = targetFile.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); 442 boolean errors = false; 443 for (int i = 0; i < markers.length; ++i) 444 { 445 IMarker marker = markers[i]; 446 if (marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO) == IMarker.SEVERITY_ERROR) 447 { 448 errors = true; 449 subProgressMonitor.subTask 450 (marker.getAttribute(IMarker.MESSAGE) + " : " + 451 (CodeGenPlugin.getPlugin().getString 452 ("jet.mark.file.line", 453 new Object [] 454 { 455 targetFile.getLocation(), 456 marker.getAttribute(IMarker.LINE_NUMBER) 457 }))); 458 } 459 } 460 461 if (!errors) 462 { 463 subProgressMonitor.subTask 464 (CodeGenPlugin.getPlugin().getString 465 ("_UI_JETLoadingClass_message", new Object [] { jetCompiler.getSkeleton().getClassName() + ".class" })); 466 467 URL url = new File (project.getLocation() + "/" + javaProject.getOutputLocation().removeFirstSegments(1) + "/").toURL(); 470 URLClassLoader theClassLoader = new URLClassLoader (new URL [] { url }, classLoader); 471 Class theClass = 472 theClassLoader.loadClass 473 ((packageName.length() == 0 ? "" : packageName + ".") + jetCompiler.getSkeleton().getClassName()); 474 String methodName = jetCompiler.getSkeleton().getMethodName(); 475 Method [] methods = theClass.getDeclaredMethods(); 476 for (int i = 0; i < methods.length; ++i) 477 { 478 if (methods[i].getName().equals(methodName)) 479 { 480 setMethod(methods[i]); 481 break; 482 } 483 } 484 } 485 486 subProgressMonitor.done(); 487 } 488 catch (CoreException exception) 489 { 490 throw new JETException(exception); 491 } 492 catch (Exception exception) 493 { 494 throw new JETException(exception); 495 } 496 finally 497 { 498 progressMonitor.done(); 499 } 500 } 501 502 525 public void addVariable(String variableName, String pluginID) throws JETException 526 { 527 Bundle bundle = Platform.getBundle(pluginID); 528 URL classpathURL = Platform.inDevelopmentMode() ? bundle.getEntry(".classpath") : null; 529 if (classpathURL != null) 530 { 531 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 532 documentBuilderFactory.setNamespaceAware(true); 533 documentBuilderFactory.setValidating(false); 534 try 535 { 536 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 537 Document document = documentBuilder.parse(new InputSource (classpathURL.toString())); 538 for (Node child = document.getDocumentElement().getFirstChild(); child != null; child = child.getNextSibling()) 539 { 540 if (child.getNodeType() == Node.ELEMENT_NODE) 541 { 542 Element classpathEntryElement = (Element )child; 543 if ("classpathentry".equals(classpathEntryElement.getNodeName()) && 544 "output".equals(classpathEntryElement.getAttribute("kind"))) 545 { 546 URI uri = URI.createURI(classpathEntryElement.getAttribute("path")).resolve(URI.createURI(classpathURL.toString())); 547 IWorkspace workspace = ResourcesPlugin.getWorkspace(); 548 IProject project = workspace.getRoot().getProject(getProjectName()); 549 if (!project.exists()) 550 { 551 project.create(new NullProgressMonitor()); 552 } 553 if (!project.isOpen()) 554 { 555 project.open(new NullProgressMonitor()); 556 } 557 IFolder folder = project.getFolder("." + pluginID); 558 if (!folder.exists()) 559 { 560 folder.createLink 561 (new Path(CommonPlugin.asLocalURI(uri).toFileString()).removeTrailingSeparator(), 562 IResource.ALLOW_MISSING_LOCAL, 563 new NullProgressMonitor()); 564 } 565 folder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); 566 IPath path = folder.getFullPath(); 567 getClasspathEntries().add(JavaCore.newLibraryEntry(path, null, null)); 568 break; 569 } 570 } 571 } 572 } 573 catch (Exception exception) 574 { 575 CodeGenPlugin.INSTANCE.log(exception); 576 } 577 } 578 else 579 { 580 CodeGenUtil.addClasspathEntries(getClasspathEntries(), variableName, pluginID); 581 } 582 } 583 584 588 public String generate(IProgressMonitor progressMonitor, Object [] arguments) throws JETException 589 { 590 if (method == null) 591 { 592 initialize(progressMonitor); 593 } 594 595 String result = ""; 596 if (method != null) 597 { 598 try 599 { 600 result = (String )method.invoke(object, arguments); 601 } 602 catch (IllegalAccessException exception) 603 { 604 throw new JETException(exception); 605 } 606 catch (InvocationTargetException exception) 607 { 608 throw new JETException(exception); 609 } 610 } 611 return result; 612 } 613 } 614 | Popular Tags |