1 11 12 package org.eclipse.pde.internal.ui.util; 13 14 import java.io.ByteArrayInputStream ; 15 import java.io.File ; 16 import java.io.FileInputStream ; 17 import java.io.IOException ; 18 import java.io.InputStream ; 19 import java.io.InputStreamReader ; 20 import java.net.MalformedURLException ; 21 import java.net.URL ; 22 import java.util.ArrayList ; 23 import java.util.Enumeration ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Map ; 27 import java.util.zip.ZipEntry ; 28 import java.util.zip.ZipException ; 29 import java.util.zip.ZipFile ; 30 31 import org.eclipse.core.resources.IContainer; 32 import org.eclipse.core.resources.IFile; 33 import org.eclipse.core.resources.IFolder; 34 import org.eclipse.core.resources.IProject; 35 import org.eclipse.core.runtime.CoreException; 36 import org.eclipse.core.runtime.FileLocator; 37 import org.eclipse.core.runtime.IPath; 38 import org.eclipse.core.runtime.IProgressMonitor; 39 import org.eclipse.core.runtime.Path; 40 import org.eclipse.core.runtime.Platform; 41 import org.eclipse.jdt.core.IClasspathEntry; 42 import org.eclipse.jdt.core.IJavaProject; 43 import org.eclipse.jdt.core.JavaCore; 44 import org.eclipse.jdt.core.JavaModelException; 45 import org.eclipse.pde.core.plugin.IPlugin; 46 import org.eclipse.pde.core.plugin.IPluginBase; 47 import org.eclipse.pde.core.plugin.IPluginModel; 48 import org.eclipse.pde.core.plugin.IPluginModelBase; 49 import org.eclipse.pde.internal.core.TargetPlatformHelper; 50 import org.eclipse.pde.internal.core.ibundle.IBundlePluginBase; 51 import org.eclipse.pde.internal.ui.PDEUIMessages; 52 import org.eclipse.pde.internal.ui.wizards.product.ISplashHandlerConstants; 53 import org.eclipse.pde.internal.ui.wizards.product.UpdateSplashHandlerAction; 54 import org.eclipse.pde.internal.ui.wizards.templates.ControlStack; 55 import org.eclipse.pde.ui.templates.IVariableProvider; 56 import org.osgi.framework.Bundle; 57 58 62 public class TemplateFileGenerator implements IVariableProvider { 63 64 67 71 public static final String KEY_PLUGIN_CLASS = "pluginClass"; 73 78 public static final String KEY_ACTIVATOR_SIMPLE = "activator"; 83 public static final String KEY_PLUGIN_ID = "pluginId"; 88 public static final String KEY_PLUGIN_NAME = "pluginName"; 93 public static final String KEY_PACKAGE_NAME = "packageName"; 95 private IProject fProject; 96 97 private IPluginModelBase fModel; 98 99 private String fPluginID; 100 101 private String fPackage; 102 103 private String fClass; 104 105 private String fTemplate; 106 107 111 public TemplateFileGenerator(IProject project, IPluginModelBase model, 112 String pluginID, String targetPackage, String targetClass, 113 String template) { 114 fProject = project; 115 fModel = model; 116 fPluginID = pluginID; 117 fPackage = targetPackage; 118 fClass = targetClass; 119 fTemplate = template; 120 } 121 122 131 public void generateFiles(IProgressMonitor monitor) throws CoreException { 132 generateFiles(monitor, getTemplateLocation()); 134 Bundle templateBundle = Platform.getBundle("org.eclipse.pde.ui.templates"); if (templateBundle == null) { 137 return; 138 } 139 generateFiles(monitor, templateBundle.getEntry("branding/")); } 141 142 public URL getTemplateLocation() { 143 Bundle bundle = Platform.getBundle("org.eclipse.pde.ui.templates"); if (bundle == null) { 145 return null; 146 } 147 148 try { 149 String [] candidates = getDirectoryCandidates(); 150 for (int i = 0; i < candidates.length; i++) { 151 if (bundle.getEntry(candidates[i]) != null) { 152 URL candidate = new URL (bundle.getEntry("/"), candidates[i]); return candidate; 154 } 155 } 156 } catch (MalformedURLException e) { 157 } 158 return null; 159 } 160 161 181 protected void generateFiles(IProgressMonitor monitor, URL locationUrl) throws CoreException { 182 monitor.setTaskName(PDEUIMessages.AbstractTemplateSection_generating); 183 184 if (locationUrl == null) { 185 return; 186 } 187 try { 188 locationUrl = FileLocator.resolve(locationUrl); 189 locationUrl = FileLocator.toFileURL(locationUrl); 190 } catch (IOException e) { 191 return; 192 } 193 if ("file".equals(locationUrl.getProtocol())) { File templateDirectory = new File (locationUrl.getFile()); 195 if (!templateDirectory.exists()) 196 return; 197 generateFiles(templateDirectory, fProject, true, false, monitor); 198 } else if ("jar".equals(locationUrl.getProtocol())) { String file = locationUrl.getFile(); 200 int exclamation = file.indexOf('!'); 201 if (exclamation < 0) 202 return; 203 URL fileUrl = null; 204 try { 205 fileUrl = new URL (file.substring(0, exclamation)); 206 } catch (MalformedURLException mue) { 207 return; 208 } 209 File pluginJar = new File (fileUrl.getFile()); 210 if (!pluginJar.exists()) 211 return; 212 String templateDirectory = file.substring(exclamation + 1); IPath path = new Path(templateDirectory); 214 ZipFile zipFile = null; 215 try { 216 zipFile = new ZipFile (pluginJar); 217 generateFiles(zipFile, path, fProject, true, false, monitor); 218 } catch (ZipException ze) { 219 } catch (IOException ioe) { 220 } finally { 221 if (zipFile != null) { 222 try { 223 zipFile.close(); 224 } catch (IOException e) { 225 } 226 } 227 } 228 229 } 230 monitor.subTask(""); monitor.worked(1); 232 } 233 234 private void generateFiles(File src, IContainer dst, boolean firstLevel, 235 boolean binary, IProgressMonitor monitor) throws CoreException { 236 File [] members = src.listFiles(); 237 238 for (int i = 0; i < members.length; i++) { 239 File member = members[i]; 240 if (member.isDirectory()) { 241 IContainer dstContainer = null; 242 243 if (firstLevel) { 244 binary = false; 245 if (!isOkToCreateFolder(member)) 246 continue; 247 248 if (member.getName().equals("java")) { IFolder sourceFolder = getSourceFolder(monitor); 250 dstContainer = generateJavaSourceFolder(sourceFolder, monitor); 251 } else if (member.getName().equals("bin")) { binary = true; 253 dstContainer = dst; 254 } 255 } 256 if (dstContainer == null) { 257 if (isOkToCreateFolder(member) == false) 258 continue; 259 String folderName = getProcessedString(member.getName(), 260 member.getName()); 261 dstContainer = dst.getFolder(new Path(folderName)); 262 } 263 if (dstContainer instanceof IFolder && !dstContainer.exists()) 264 ((IFolder) dstContainer).create(true, true, monitor); 265 generateFiles(member, dstContainer, false, binary, monitor); 266 } else { 267 if (isOkToCreateFile(member)) { 268 if (firstLevel) 269 binary = false; 270 InputStream in = null; 271 try { 272 in = new FileInputStream (member); 273 copyFile(member.getName(), in, dst, binary, monitor); 274 } catch (IOException ioe) { 275 } finally { 276 if (in != null) 277 try { 278 in.close(); 279 } catch (IOException ioe2) { 280 } 281 } 282 } 283 } 284 } 285 } 286 287 private void copyFile(String fileName, InputStream input, IContainer dst, boolean binary, 288 IProgressMonitor monitor) throws CoreException { 289 String targetFileName = getProcessedString(fileName, fileName); 290 291 monitor.subTask(targetFileName); 292 IFile dstFile = dst.getFile(new Path(targetFileName)); 293 294 try { 295 InputStream stream = getProcessedStream(fileName, input, binary); 296 if (dstFile.exists()) { 297 dstFile.setContents(stream, true, true, monitor); 298 } else { 299 dstFile.create(stream, true, monitor); 300 } 301 stream.close(); 302 303 } catch (IOException e) { 304 } 305 } 306 307 private void generateFiles(ZipFile zipFile, IPath path, IContainer dst, 308 boolean firstLevel, boolean binary, IProgressMonitor monitor) 309 throws CoreException { 310 int pathLength = path.segmentCount(); 311 Map childZipEntries = new HashMap (); 314 for (Enumeration zipEntries = zipFile.entries(); zipEntries 315 .hasMoreElements();) { 316 ZipEntry zipEntry = (ZipEntry ) zipEntries.nextElement(); 317 IPath entryPath = new Path(zipEntry.getName()); 318 if (entryPath.segmentCount() <= pathLength) { 319 continue; 321 } 322 if (!path.isPrefixOf(entryPath)) { 323 continue; 325 } 326 if (entryPath.segmentCount() == pathLength + 1) { 327 childZipEntries.put(zipEntry.getName(), zipEntry); 328 } else { 329 String name = entryPath.uptoSegment( 330 pathLength + 1).addTrailingSeparator().toString(); 331 if(!childZipEntries.containsKey(name)){ 332 ZipEntry dirEntry = new ZipEntry (name); 333 childZipEntries.put(name, dirEntry); 334 } 335 } 336 } 337 338 for (Iterator it = childZipEntries.values().iterator(); it.hasNext();) { 339 ZipEntry zipEnry = (ZipEntry ) it.next(); 340 String name = new Path(zipEnry.getName()).lastSegment().toString(); 341 if (zipEnry.isDirectory()) { 342 IContainer dstContainer = null; 343 344 if (firstLevel) { 345 binary = false; 346 if (name.equals("java")) { IFolder sourceFolder = getSourceFolder(monitor); 348 dstContainer = generateJavaSourceFolder(sourceFolder, 349 monitor); 350 } else if (name.equals("bin")) { binary = true; 352 dstContainer = dst; 353 } 354 } 355 if (dstContainer == null) { 356 if (isOkToCreateFolder(new File (path.toFile(), name)) == false) 357 continue; 358 String folderName = getProcessedString(name, name); 359 dstContainer = dst.getFolder(new Path(folderName)); 360 } 361 if (dstContainer instanceof IFolder && !dstContainer.exists()) 362 ((IFolder) dstContainer).create(true, true, monitor); 363 generateFiles(zipFile, path.append(name), dstContainer, false, 364 binary, monitor); 365 } else { 366 if (isOkToCreateFile(new File (path.toFile(), name))) { 367 if (firstLevel) 368 binary = false; 369 InputStream in = null; 370 try { 371 in = zipFile.getInputStream(zipEnry); 372 copyFile(name, in, dst, binary, monitor); 373 } catch (IOException ioe) { 374 } finally { 375 if (in != null) 376 try { 377 in.close(); 378 } catch (IOException ioe2) { 379 } 380 } 381 } 382 } 383 } 384 } 385 386 397 protected boolean isOkToCreateFolder(File sourceFolder) { 398 boolean extensibleTemplateSelected = 399 UpdateSplashHandlerAction.isExtensibleTemplateSelected(fTemplate); 400 String sourceFolderString = sourceFolder.toString(); 401 402 if ((extensibleTemplateSelected == false) && 403 sourceFolderString.endsWith("icons")) { return false; 405 } else if ((extensibleTemplateSelected == false) && 406 sourceFolderString.endsWith("schema")) { return false; 408 } 409 410 return true; 411 } 412 413 425 protected boolean isOkToCreateFile(File sourceFile) { 426 String javaSuffix = ".java"; String targetFile = fClass + javaSuffix; 428 String copyFile = sourceFile.toString(); 429 if (copyFile.endsWith(javaSuffix)) { 432 if ((copyFile.endsWith(targetFile) == false) || 433 fProject.exists(new Path("src" + '/' + fPackage.replace('.', '/') + '/' + targetFile))) { return false; 435 } 436 } else if (copyFile.endsWith("splash.bmp") && (fProject.exists(new Path("splash.bmp")))) { return false; 439 } else if (copyFile.endsWith(".png")) { if (copyFile.endsWith("af.png") && fProject.exists(new Path("icons/af.png"))) { return false; 443 } else if (copyFile.endsWith("embedded.png") && fProject.exists(new Path("icons/embedded.png"))) { return false; 446 } else if (copyFile.endsWith("enterprise.png") && fProject.exists(new Path("icons/enterprise.png"))) { return false; 449 } else if (copyFile.endsWith("rcp.png") && fProject.exists(new Path("icons/rcp.png"))) { return false; 452 } else if (copyFile.endsWith("languages.png") && fProject.exists(new Path("icons/languages.png"))) { return false; 455 } 456 } else if (copyFile.endsWith("splashExtension.exsd") && (fProject.exists(new Path("schema/splashExtension.exsd")))) { return false; 459 } 460 461 return true; 462 } 463 464 475 476 protected IFolder getSourceFolder(IProgressMonitor monitor) 477 throws CoreException { 478 IFolder sourceFolder = null; 479 480 try { 481 IJavaProject javaProject = JavaCore.create(fProject); 482 IClasspathEntry[] classpath = javaProject.getRawClasspath(); 483 for (int i = 0; i < classpath.length; i++) { 484 IClasspathEntry entry = classpath[i]; 485 if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { 486 IPath path = entry.getPath().removeFirstSegments(1); 487 if (path.segmentCount() > 0) 488 sourceFolder = fProject.getFolder(path); 489 break; 490 } 491 } 492 } catch (JavaModelException e) { 493 } 494 return sourceFolder; 495 } 496 497 500 501 public Object getValue(String key) { 502 return getKeyValue(key); 503 } 504 505 private IFolder generateJavaSourceFolder(IFolder sourceFolder, 506 IProgressMonitor monitor) throws CoreException { 507 Object packageValue = getValue(KEY_PACKAGE_NAME); 508 String packageName = packageValue != null 510 ? packageValue.toString() 511 : null; 512 if (packageName == null) 513 packageName = fModel.getPluginBase().getId(); 514 IPath path = new Path(packageName.replace('.', File.separatorChar)); 515 if (sourceFolder != null) 516 path = sourceFolder.getProjectRelativePath().append(path); 517 518 for (int i = 1; i <= path.segmentCount(); i++) { 519 IPath subpath = path.uptoSegment(i); 520 IFolder subfolder = fProject.getFolder(subpath); 521 if (subfolder.exists() == false) 522 subfolder.create(true, true, monitor); 523 } 524 return fProject.getFolder(path); 525 } 526 527 private String getProcessedString(String fileName, String source) { 528 if (source.indexOf('$') == -1) 529 return source; 530 int loc = -1; 531 StringBuffer buffer = new StringBuffer (); 532 boolean replacementMode = false; 533 for (int i = 0; i < source.length(); i++) { 534 char c = source.charAt(i); 535 if (c == '$') { 536 if (replacementMode) { 537 String key = source.substring(loc, i); 538 String value = key.length() == 0 ? "$" : getReplacementString(fileName, key); 540 buffer.append(value); 541 replacementMode = false; 542 } else { 543 replacementMode = true; 544 loc = i + 1; 545 continue; 546 } 547 } else if (!replacementMode) 548 buffer.append(c); 549 } 550 return buffer.toString(); 551 } 552 553 560 public String getReplacementString(String fileName, String key) { 561 String result = getKeyValue(key); 562 return result != null ? result : key; 563 } 564 565 private String getKeyValue(String key) { 566 if (fModel == null) 567 return null; 568 569 if (key.equals(KEY_PLUGIN_CLASS) && fModel instanceof IPluginModel) { 571 IPlugin plugin = (IPlugin) fModel.getPluginBase(); 572 return plugin.getClassName(); 573 } 574 575 if (key.equals(KEY_ACTIVATOR_SIMPLE) && fModel instanceof IPluginModel) { 577 IPlugin plugin = (IPlugin) fModel.getPluginBase(); 578 String qualified = plugin.getClassName(); 579 if (qualified != null) { 580 int lastDot = qualified.lastIndexOf('.'); 581 return (lastDot != -1 && lastDot < qualified.length() - 1) ? qualified.substring(lastDot + 1) : qualified; 582 } 583 } 584 585 if (key.equals(KEY_PLUGIN_ID)) { 586 return fPluginID; 587 } 591 if (key.equals(KEY_PLUGIN_NAME)) { 593 IPluginBase plugin = fModel.getPluginBase(); 594 return plugin.getTranslatedName(); 595 } 596 597 if (key.equals(KEY_PACKAGE_NAME) && fModel instanceof IPluginModel) { 598 return fPackage; 599 } 607 return null; 608 } 609 610 private InputStream getProcessedStream(String fileName, InputStream stream, 611 boolean binary) throws IOException , CoreException { 612 if (binary) 613 return stream; 614 615 InputStreamReader reader = new InputStreamReader (stream); 616 int bufsize = 1024; 617 char[] cbuffer = new char[bufsize]; 618 int read = 0; 619 StringBuffer keyBuffer = new StringBuffer (); 620 StringBuffer outBuffer = new StringBuffer (); 621 StringBuffer preBuffer = new StringBuffer (); 622 boolean newLine = true; 623 ControlStack preStack = new ControlStack(); 624 preStack.setValueProvider(this); 625 626 boolean replacementMode = false; 627 boolean preprocessorMode = false; 628 boolean escape = false; 629 while (read != -1) { 630 read = reader.read(cbuffer); 631 for (int i = 0; i < read; i++) { 632 char c = cbuffer[i]; 633 634 if (escape) { 635 StringBuffer buf = preprocessorMode ? preBuffer : outBuffer; 636 buf.append(c); 637 escape = false; 638 continue; 639 } 640 641 if (newLine && c == '%') { 642 preprocessorMode = true; 644 preBuffer.delete(0, preBuffer.length()); 645 continue; 646 } 647 if (preprocessorMode) { 648 if (c == '\\') { 649 escape = true; 650 continue; 651 } 652 if (c == '\n') { 653 preprocessorMode = false; 655 newLine = true; 656 String line = preBuffer.toString().trim(); 657 preStack.processLine(line); 658 continue; 659 } 660 preBuffer.append(c); 661 662 continue; 663 } 664 665 if (preStack.getCurrentState() == false) { 666 continue; 667 } 668 669 if (c == '$') { 670 if (replacementMode) { 671 replacementMode = false; 672 String key = keyBuffer.toString(); 673 String value = key.length() == 0 ? "$" : getReplacementString(fileName, key); 675 outBuffer.append(value); 676 keyBuffer.delete(0, keyBuffer.length()); 677 } else { 678 replacementMode = true; 679 } 680 } else { 681 if (replacementMode) 682 keyBuffer.append(c); 683 else { 684 outBuffer.append(c); 685 if (c == '\n') { 686 newLine = true; 687 } else 688 newLine = false; 689 } 690 } 691 } 692 } 693 return new ByteArrayInputStream (outBuffer.toString().getBytes( 694 fProject.getDefaultCharset())); 695 } 696 697 private String [] getDirectoryCandidates() { 698 double version = getTargetVersion(); 699 ArrayList result = new ArrayList (); 700 if (version >= 3.3) 701 result.add("templates_3.3" + "/" + getSectionId() + "/"); if (version >= 3.2) 703 result.add("templates_3.2" + "/" + getSectionId() + "/"); if (version >= 3.1) 705 result.add("templates_3.1" + "/" + getSectionId() + "/"); if (version >= 3.0) 707 result.add("templates_3.0" + "/" + getSectionId() + "/"); return (String [])result.toArray(new String [result.size()]); 709 } 710 711 public String getSectionId() { 712 return ISplashHandlerConstants.F_UNQUALIFIED_EXTENSION_ID; 713 } 714 715 protected double getTargetVersion() { 716 try { 717 IPluginBase plugin = fModel.getPluginBase(); 718 if (plugin instanceof IBundlePluginBase) 719 return Double.parseDouble(((IBundlePluginBase)plugin).getTargetVersion()); 720 } catch (NumberFormatException e) { 721 } 722 return TargetPlatformHelper.getTargetVersion(); 723 } 724 725 } 726 | Popular Tags |