Line 0
Link Here
|
|
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2008 Sybase Inc. and others. |
3 |
* |
4 |
* All rights reserved. This program and the accompanying materials |
5 |
* are made available under the terms of the Eclipse Public License v1.0 |
6 |
* which accompanies this distribution, and is available at |
7 |
* http://www.eclipse.org/legal/epl-v10.html |
8 |
* |
9 |
* Contributors: |
10 |
* Feng Wang (Sybase) - initial implementation |
11 |
*******************************************************************************/ |
12 |
package org.eclipse.mtj.ui.template; |
13 |
|
14 |
import java.io.File; |
15 |
import java.io.FileInputStream; |
16 |
import java.io.FileNotFoundException; |
17 |
import java.io.FileOutputStream; |
18 |
import java.io.IOException; |
19 |
import java.io.InputStream; |
20 |
import java.io.InputStreamReader; |
21 |
import java.io.OutputStreamWriter; |
22 |
import java.io.Reader; |
23 |
import java.io.UnsupportedEncodingException; |
24 |
import java.lang.reflect.InvocationTargetException; |
25 |
import java.net.URL; |
26 |
import java.util.Enumeration; |
27 |
import java.util.HashMap; |
28 |
import java.util.Map; |
29 |
import java.util.regex.Matcher; |
30 |
import java.util.regex.Pattern; |
31 |
import java.util.zip.ZipEntry; |
32 |
import java.util.zip.ZipFile; |
33 |
|
34 |
import org.eclipse.core.resources.IFile; |
35 |
import org.eclipse.core.resources.IResource; |
36 |
import org.eclipse.core.resources.IWorkspaceRoot; |
37 |
import org.eclipse.core.resources.ResourcesPlugin; |
38 |
import org.eclipse.core.runtime.CoreException; |
39 |
import org.eclipse.core.runtime.FileLocator; |
40 |
import org.eclipse.core.runtime.IPath; |
41 |
import org.eclipse.core.runtime.IProgressMonitor; |
42 |
import org.eclipse.core.runtime.IStatus; |
43 |
import org.eclipse.core.runtime.Path; |
44 |
import org.eclipse.core.runtime.SafeRunner; |
45 |
import org.eclipse.jdt.core.ICompilationUnit; |
46 |
import org.eclipse.jdt.core.IJavaElement; |
47 |
import org.eclipse.jdt.core.IJavaProject; |
48 |
import org.eclipse.jdt.core.IPackageFragmentRoot; |
49 |
import org.eclipse.jdt.core.IType; |
50 |
import org.eclipse.jdt.core.JavaCore; |
51 |
import org.eclipse.jface.operation.IRunnableWithProgress; |
52 |
import org.eclipse.jface.wizard.Wizard; |
53 |
import org.eclipse.mtj.core.internal.MTJCorePlugin; |
54 |
import org.eclipse.mtj.core.internal.utils.Utils; |
55 |
import org.eclipse.mtj.core.model.jad.ApplicationDescriptor; |
56 |
import org.eclipse.mtj.core.model.project.IMidletSuiteProject; |
57 |
import org.eclipse.mtj.core.model.project.MidletSuiteFactory; |
58 |
import org.eclipse.mtj.ui.internal.template.MidletTemplateWizardPage; |
59 |
import org.eclipse.mtj.ui.internal.template.TemplateMessages; |
60 |
import org.eclipse.mtj.ui.internal.utils.LogAndDisplaySafeRunnable; |
61 |
import org.eclipse.mtj.ui.internal.wizards.template.TemplateWizardMessages; |
62 |
|
63 |
/** |
64 |
* You should subclass this class to create your MidletTemplateWizard. You |
65 |
* should |
66 |
* <p> |
67 |
* 1. Provide a MidletTemplate by override {@link #createTemplate()} method |
68 |
* <p> |
69 |
* 2. Provide the URL of your template by override |
70 |
* {@link #getTemplateFolderURL()} |
71 |
* <p> |
72 |
* Typically you do not need add any more page to this wizard. |
73 |
* |
74 |
* @author wangf |
75 |
* |
76 |
*/ |
77 |
public abstract class MidletTemplateWizard extends Wizard { |
78 |
|
79 |
private MidletTemplate template; |
80 |
private Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\$.+?\\$"); |
81 |
/** |
82 |
* The Java source folder of your MTJ Midlet Suite project. You can choose |
83 |
* it on the wizard page. |
84 |
*/ |
85 |
private IPackageFragmentRoot javaRoot; |
86 |
/** |
87 |
* The resource folder of your MTJ Midlet Suite project. You can choose it |
88 |
* on the wizard page. |
89 |
*/ |
90 |
private IPackageFragmentRoot resourceRoot; |
91 |
|
92 |
public MidletTemplateWizard() { |
93 |
this.template = createTemplate(); |
94 |
setWindowTitle(TemplateMessages.MidletTemplateWizard_title); |
95 |
setNeedsProgressMonitor(true); |
96 |
} |
97 |
|
98 |
@Override |
99 |
public void addPages() { |
100 |
MidletTemplateWizardPage page = new MidletTemplateWizardPage(template); |
101 |
addPage(page); |
102 |
} |
103 |
|
104 |
@Override |
105 |
public boolean performFinish() { |
106 |
boolean completed = true; |
107 |
|
108 |
IRunnableWithProgress runable = getCreateMidletOperation(); |
109 |
try { |
110 |
getContainer().run(false, true, runable); |
111 |
} catch (InvocationTargetException e) { |
112 |
MTJCorePlugin.log(IStatus.ERROR, e); |
113 |
completed = false; |
114 |
} catch (InterruptedException e) { |
115 |
MTJCorePlugin.log(IStatus.ERROR, e); |
116 |
completed = false; |
117 |
} |
118 |
|
119 |
return completed; |
120 |
} |
121 |
|
122 |
/** |
123 |
* Set the Java source folder of your MTJ Midlet Suite project. User can |
124 |
* choose the folder on the wizard page. |
125 |
* |
126 |
* @param javaRoot |
127 |
*/ |
128 |
public void setJavaRoot(IPackageFragmentRoot javaRoot) { |
129 |
this.javaRoot = javaRoot; |
130 |
} |
131 |
|
132 |
/** |
133 |
* Set the resource folder of your MTJ Midlet Suite project. User can choose |
134 |
* it on the wizard page. |
135 |
* |
136 |
* @param resourceRoot |
137 |
*/ |
138 |
public void setResourceRoot(IPackageFragmentRoot resourceRoot) { |
139 |
this.resourceRoot = resourceRoot; |
140 |
} |
141 |
|
142 |
/** |
143 |
* Return a IRunnableWithProgress that will run in the |
144 |
* {@link #performFinish()} method. This runnable create the Midlet from |
145 |
* template. |
146 |
* |
147 |
* @return |
148 |
*/ |
149 |
private IRunnableWithProgress getCreateMidletOperation() { |
150 |
IRunnableWithProgress runnable = null; |
151 |
|
152 |
URL templateFolderURL = getTemplateFolderURL(); |
153 |
try { |
154 |
templateFolderURL = FileLocator.resolve(templateFolderURL); |
155 |
templateFolderURL = FileLocator.toFileURL(templateFolderURL); |
156 |
} catch (IOException e) { |
157 |
return null; |
158 |
} |
159 |
if ("file".equals(templateFolderURL.getProtocol())) { //$NON-NLS-1$ |
160 |
runnable = getDirCopyRunable(templateFolderURL); |
161 |
} else if ("jar".equals(templateFolderURL.getProtocol())) { //$NON-NLS-1$ |
162 |
runnable = getZipCopyRunable(templateFolderURL); |
163 |
} |
164 |
|
165 |
return runnable; |
166 |
} |
167 |
|
168 |
/** |
169 |
* Get a IRunnableWithProgress which perform the operation that copy |
170 |
* templates from a jar file. |
171 |
* |
172 |
* @param jarURL |
173 |
* - the URL of the Jar file which contains template. |
174 |
* @return |
175 |
*/ |
176 |
private IRunnableWithProgress getZipCopyRunable(URL jarURL) { |
177 |
final String file = jarURL.getFile(); |
178 |
final int exclamation = file.indexOf('!'); |
179 |
if (exclamation < 0) { |
180 |
return null; |
181 |
} |
182 |
IRunnableWithProgress runnable = new IRunnableWithProgress() { |
183 |
|
184 |
public void run(IProgressMonitor monitor) |
185 |
throws InvocationTargetException, InterruptedException { |
186 |
SafeRunner.run(new LogAndDisplaySafeRunnable(getShell(), |
187 |
TemplateWizardMessages.ErrorDialogTitle_duringCopy) { |
188 |
|
189 |
public void run() throws Exception { |
190 |
URL fileUrl = new URL(file.substring(0, exclamation)); |
191 |
File pluginJar = new File(fileUrl.getFile()); |
192 |
String templateDir = file.substring(exclamation + 1); |
193 |
IPath templatePath = new Path(templateDir); |
194 |
ZipFile zipFile = null; |
195 |
try { |
196 |
zipFile = new ZipFile(pluginJar); |
197 |
generateFilesFromZip(zipFile, templatePath); |
198 |
} finally { |
199 |
if (zipFile != null) { |
200 |
zipFile.close(); |
201 |
} |
202 |
} |
203 |
} |
204 |
|
205 |
}); |
206 |
|
207 |
} |
208 |
|
209 |
}; |
210 |
return runnable; |
211 |
} |
212 |
|
213 |
/** |
214 |
* Generate Midlet files including Java source code and resource files from |
215 |
* jar file. |
216 |
* |
217 |
* @param zipFile |
218 |
* @param templatePath |
219 |
* @throws CoreException |
220 |
* @throws IOException |
221 |
*/ |
222 |
private void generateFilesFromZip(ZipFile zipFile, IPath templatePath) |
223 |
throws IOException, CoreException { |
224 |
Map<IPath, ZipEntry>[] entryMaps = collectJavaAndResourceEntries( |
225 |
zipFile, templatePath); |
226 |
|
227 |
Map<IPath, ZipEntry> javaEntries = entryMaps[0]; |
228 |
copyAndModifyJavaTemplateFromZip(zipFile, javaEntries); |
229 |
|
230 |
Map<IPath, ZipEntry> resourceEntries = entryMaps[1]; |
231 |
copyResoueceFromZip(zipFile, resourceEntries); |
232 |
} |
233 |
|
234 |
/** |
235 |
* Return a array contains 2 maps. The first map contains all the Java |
236 |
* source file template ZIP entries. The second map contains all the |
237 |
* resource file ZIP entries. |
238 |
* |
239 |
* @param zipFile |
240 |
* @param templatePath |
241 |
* @return |
242 |
*/ |
243 |
private Map<IPath, ZipEntry>[] collectJavaAndResourceEntries( |
244 |
ZipFile zipFile, IPath templatePath) { |
245 |
IPath javaPath = templatePath.append(MidletTemplate.JAVA_FOLDER); |
246 |
IPath resourcePath = templatePath |
247 |
.append(MidletTemplate.RESOURCE_FOLDER); |
248 |
|
249 |
Map<IPath, ZipEntry> javaEntries = new HashMap<IPath, ZipEntry>(); |
250 |
Map<IPath, ZipEntry> resourceEntries = new HashMap<IPath, ZipEntry>(); |
251 |
|
252 |
for (Enumeration<?> zipEntries = zipFile.entries(); zipEntries |
253 |
.hasMoreElements();) { |
254 |
ZipEntry zipEntry = (ZipEntry) zipEntries.nextElement(); |
255 |
IPath entryPath = new Path(zipEntry.getName()); |
256 |
if (javaPath.isPrefixOf(entryPath) && !zipEntry.isDirectory()) { |
257 |
IPath key = entryPath.removeFirstSegments(javaPath |
258 |
.segmentCount()); |
259 |
javaEntries.put(key, zipEntry); |
260 |
} else if (resourcePath.isPrefixOf(entryPath) |
261 |
&& !zipEntry.isDirectory()) { |
262 |
IPath key = entryPath.removeFirstSegments(resourcePath |
263 |
.segmentCount()); |
264 |
resourceEntries.put(key, zipEntry); |
265 |
} |
266 |
} |
267 |
@SuppressWarnings("unchecked") |
268 |
// Do NOT change the sequence of the 2 element |
269 |
Map<IPath, ZipEntry>[] entryMaps = new Map[] { javaEntries, |
270 |
resourceEntries }; |
271 |
return entryMaps; |
272 |
} |
273 |
|
274 |
/** |
275 |
* Get a IRunnableWithProgress which perform the operation that copy |
276 |
* templates from a folder. |
277 |
* |
278 |
* @param templateFolderURL |
279 |
* - The URL of the folder which contains template. |
280 |
* @return |
281 |
*/ |
282 |
private IRunnableWithProgress getDirCopyRunable(URL templateFolderURL) { |
283 |
File templateDirectory = new File(templateFolderURL.getFile()); |
284 |
if (!templateDirectory.exists()) |
285 |
return null; |
286 |
final File javaTemplateDir = new File(templateDirectory, |
287 |
MidletTemplate.JAVA_FOLDER); |
288 |
final File resourceFileDir = new File(templateDirectory, |
289 |
MidletTemplate.RESOURCE_FOLDER); |
290 |
|
291 |
IRunnableWithProgress runnable = new IRunnableWithProgress() { |
292 |
|
293 |
public void run(final IProgressMonitor monitor) |
294 |
throws InvocationTargetException, InterruptedException { |
295 |
SafeRunner.run(new LogAndDisplaySafeRunnable(getShell(), |
296 |
TemplateWizardMessages.ErrorDialogTitle_duringCopy) { |
297 |
|
298 |
public void run() throws Exception { |
299 |
// Do copy |
300 |
copyAndModifyJavaTemplateFromDir(javaTemplateDir, |
301 |
getMidletProjectPackageFolder(), monitor); |
302 |
copyResourceFromDir(resourceFileDir, monitor); |
303 |
// refresh |
304 |
javaRoot.getResource().refreshLocal( |
305 |
IResource.DEPTH_INFINITE, monitor); |
306 |
resourceRoot.getResource().refreshLocal( |
307 |
IResource.DEPTH_INFINITE, monitor); |
308 |
} |
309 |
|
310 |
}); |
311 |
} |
312 |
|
313 |
}; |
314 |
return runnable; |
315 |
} |
316 |
|
317 |
/** |
318 |
* Copy & substitute template string of all Java template ZIP entries from |
319 |
* jar file. And then add Midlet declaration into JAD. |
320 |
* |
321 |
* @param zipFile |
322 |
* - Jar file contains templates. |
323 |
* @param javaEntries |
324 |
* - a map contains all the Java template ZIP entries. |
325 |
* @throws UnsupportedEncodingException |
326 |
* @throws IOException |
327 |
* @throws FileNotFoundException |
328 |
* @throws CoreException |
329 |
*/ |
330 |
private void copyAndModifyJavaTemplateFromZip(ZipFile zipFile, |
331 |
Map<IPath, ZipEntry> javaEntries) |
332 |
throws UnsupportedEncodingException, IOException, |
333 |
FileNotFoundException, CoreException { |
334 |
for (IPath key : javaEntries.keySet()) { |
335 |
// Get StringBuffer before template substituting |
336 |
StringBuffer sb = getSbBeforeSubstituteTemplates(zipFile |
337 |
.getInputStream(javaEntries.get(key))); |
338 |
// Get StringBuffer before template substituting |
339 |
sb = getSbAfterSubstituteTemplates(sb); |
340 |
// Get the absolute path of the destination file. |
341 |
IPath destFilePath = getMidletProjectPackagePath().append(key); |
342 |
String destFileName = substituteJavaTemplateFileName(destFilePath |
343 |
.lastSegment()); |
344 |
destFilePath = destFilePath.removeLastSegments(1).append( |
345 |
destFileName); |
346 |
// Do file writing |
347 |
writeFile(new File(destFilePath.toOSString()), sb); |
348 |
// Must refresh local before add Midlet declaration to JAD |
349 |
javaRoot.getResource().refreshLocal(IResource.DEPTH_INFINITE, null); |
350 |
// Add Midlet declaration to JAD |
351 |
addMidletToJAD(destFilePath.toFile(), null); |
352 |
} |
353 |
} |
354 |
|
355 |
/** |
356 |
* Copy & substitute template string of all Java template files from a |
357 |
* directory contains templates. And then add Midlet declaration into JAD. |
358 |
* |
359 |
* @param source |
360 |
* @param destination |
361 |
* @param monitor |
362 |
* @throws IOException |
363 |
* @throws CoreException |
364 |
*/ |
365 |
private void copyAndModifyJavaTemplateFromDir(File source, |
366 |
File destination, IProgressMonitor monitor) throws IOException, |
367 |
CoreException { |
368 |
if (source.exists() && source.isDirectory()) { |
369 |
destination.mkdirs(); |
370 |
|
371 |
File[] sources = source.listFiles(); |
372 |
for (int i = 0; i < sources.length; i++) { |
373 |
File currentSrc = sources[i]; |
374 |
String currentDestName = substituteJavaTemplateFileName(currentSrc |
375 |
.getName()); |
376 |
File currentDest = new File(destination, currentDestName); |
377 |
|
378 |
if (currentSrc.isDirectory()) { |
379 |
copyAndModifyJavaTemplateFromDir(currentSrc, currentDest, |
380 |
monitor); |
381 |
} else { |
382 |
StringBuffer sb = getSbBeforeSubstituteTemplates(new FileInputStream( |
383 |
currentSrc)); |
384 |
sb = getSbAfterSubstituteTemplates(sb); |
385 |
writeFile(currentDest, sb); |
386 |
// Must refresh local before add Midlet declaration to JAD |
387 |
javaRoot.getResource().refreshLocal( |
388 |
IResource.DEPTH_INFINITE, monitor); |
389 |
// Add Midlet declaration to JAD |
390 |
addMidletToJAD(currentDest, monitor); |
391 |
} |
392 |
} |
393 |
} |
394 |
} |
395 |
|
396 |
/** |
397 |
* Copy all of the resource files from Jar file to MTJ Midlet suite project |
398 |
* resource folder. |
399 |
* |
400 |
* @param zipFile |
401 |
* - the Jar file contains templates |
402 |
* @param resourceEntries |
403 |
* - a map contains all the resource ZIP entries. |
404 |
* @throws IOException |
405 |
* @throws CoreException |
406 |
*/ |
407 |
private void copyResoueceFromZip(ZipFile zipFile, |
408 |
Map<IPath, ZipEntry> resourceEntries) throws IOException, |
409 |
CoreException { |
410 |
for (IPath key : resourceEntries.keySet()) { |
411 |
InputStream in = zipFile.getInputStream(resourceEntries.get(key)); |
412 |
IPath destFilePath = getMidletProjectResourcePath().append(key); |
413 |
writeFile(destFilePath, in); |
414 |
resourceRoot.getResource().refreshLocal(IResource.DEPTH_INFINITE, |
415 |
null); |
416 |
} |
417 |
} |
418 |
|
419 |
/** |
420 |
* Copy all of the resource files from template resource directory to MTJ |
421 |
* Midlet suite project resource folder. |
422 |
* |
423 |
* @param resourceDir |
424 |
* - Directory contains template resource files. |
425 |
* @param monitor |
426 |
* @throws IOException |
427 |
*/ |
428 |
private void copyResourceFromDir(File resourceDir, IProgressMonitor monitor) |
429 |
throws IOException { |
430 |
Utils.copyDirectory(resourceDir, getMidletProjectResourceDir(), null); |
431 |
} |
432 |
|
433 |
/** |
434 |
* Get the Java package folder of the MTJ Midlet Suite Project. |
435 |
* |
436 |
* @return |
437 |
*/ |
438 |
private File getMidletProjectPackageFolder() { |
439 |
IPath packagePath = getMidletProjectPackagePath(); |
440 |
File packageDir = packagePath.toFile(); |
441 |
return packageDir; |
442 |
} |
443 |
|
444 |
/** |
445 |
* Get the Java package path of the MTJ Midlet Suite Project. |
446 |
* |
447 |
* @return |
448 |
*/ |
449 |
private IPath getMidletProjectPackagePath() { |
450 |
IPath srcPath = getMidletProjectSrcPath(); |
451 |
String packageName = template |
452 |
.getSubstituteStringFor(MidletTemplate.OPTION_PACKAGE); |
453 |
IPath packagePath = srcPath.append(packageName.replace(".", "/"));//$NON-NLS-1$ |
454 |
return packagePath; |
455 |
} |
456 |
|
457 |
/** |
458 |
* Get the path of the MTJ Midlet Suite project Source folder. |
459 |
* |
460 |
* @return |
461 |
*/ |
462 |
private IPath getMidletProjectSrcPath() { |
463 |
IPath srcPath = null; |
464 |
srcPath = javaRoot.getResource().getLocation(); |
465 |
return srcPath; |
466 |
} |
467 |
|
468 |
/** |
469 |
* Get the MTJ Midlet Suite project resource folder. |
470 |
* |
471 |
* @return |
472 |
*/ |
473 |
private File getMidletProjectResourceDir() { |
474 |
IPath resourcePath = getMidletProjectResourcePath(); |
475 |
return resourcePath.toFile(); |
476 |
} |
477 |
|
478 |
/** |
479 |
* Get the MTJ Midlet Suite project resource path. |
480 |
* |
481 |
* @return |
482 |
*/ |
483 |
private IPath getMidletProjectResourcePath() { |
484 |
IPath resourcePath = resourceRoot.getResource().getLocation(); |
485 |
return resourcePath; |
486 |
} |
487 |
|
488 |
/** |
489 |
* Write a StringBuffer to a file. |
490 |
* |
491 |
* @param destFile |
492 |
* - the destination file. |
493 |
* @param sb |
494 |
* - the StringBuffer to be written to the destination file. |
495 |
* @throws FileNotFoundException |
496 |
* @throws UnsupportedEncodingException |
497 |
* @throws IOException |
498 |
*/ |
499 |
private void writeFile(File destFile, StringBuffer sb) |
500 |
throws FileNotFoundException, UnsupportedEncodingException, |
501 |
IOException { |
502 |
// Make necessary Dirs |
503 |
IPath path = new Path(destFile.getPath()); |
504 |
path.removeLastSegments(1).toFile().mkdirs(); |
505 |
// Do write |
506 |
FileOutputStream fos = new FileOutputStream(destFile); |
507 |
OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8"); |
508 |
writer.write(sb.toString()); |
509 |
writer.close(); |
510 |
} |
511 |
|
512 |
/** |
513 |
* Write the content from a InputStream to a file. |
514 |
* |
515 |
* @param destPath |
516 |
* - the path of the destination file. |
517 |
* @param in |
518 |
* - the ImputSteam whose content will be written to the |
519 |
* destination file. |
520 |
* @throws IOException |
521 |
*/ |
522 |
private void writeFile(IPath destPath, InputStream in) throws IOException { |
523 |
// Make necessary Dirs |
524 |
destPath.removeLastSegments(1).toFile().mkdirs(); |
525 |
// Do write |
526 |
FileOutputStream out = new FileOutputStream(destPath.toFile()); |
527 |
Utils.copyInputToOutput(in, out); |
528 |
} |
529 |
|
530 |
/** |
531 |
* Add the created Midlet declaration to JAD file. |
532 |
* |
533 |
* @param javaSourceFile |
534 |
* - the Java source file just generated from a template. |
535 |
* @param monitor |
536 |
* @throws IOException |
537 |
* @throws CoreException |
538 |
*/ |
539 |
private void addMidletToJAD(File javaSourceFile, IProgressMonitor monitor) |
540 |
throws IOException, CoreException { |
541 |
// create ICompilationUnit from File |
542 |
String path = javaSourceFile.getAbsolutePath(); |
543 |
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
544 |
IFile javaSrcFile = root.getFileForLocation(new Path(path)); |
545 |
ICompilationUnit cu = (ICompilationUnit) JavaCore.create(javaSrcFile); |
546 |
if (cu == null) { |
547 |
return; |
548 |
} |
549 |
// find Midlets and add them to JAD |
550 |
IType[] types = cu.getAllTypes(); |
551 |
for (IType type : types) { |
552 |
if (Utils.isMidlet(type, monitor)) { |
553 |
writeMidletDeclarationToJAD(type, monitor); |
554 |
} |
555 |
} |
556 |
} |
557 |
|
558 |
/** |
559 |
* Add Midlet declaration to JAD file. |
560 |
* |
561 |
* @param midlet |
562 |
* @param monitor |
563 |
* |
564 |
* @throws IOException |
565 |
* @throws CoreException |
566 |
*/ |
567 |
private void writeMidletDeclarationToJAD(IType midlet, |
568 |
IProgressMonitor monitor) throws IOException, CoreException { |
569 |
// Pull out the midlet suite that the type was created in |
570 |
IJavaProject javaProject = (IJavaProject) midlet |
571 |
.getAncestor(IJavaElement.JAVA_PROJECT); |
572 |
IMidletSuiteProject midletSuite = MidletSuiteFactory |
573 |
.getMidletSuiteProject(javaProject); |
574 |
|
575 |
ApplicationDescriptor desc = midletSuite.getApplicationDescriptor(); |
576 |
if (desc != null) { |
577 |
ApplicationDescriptor.MidletDefinition def = new ApplicationDescriptor.MidletDefinition( |
578 |
desc.getMidletCount() + 1, midlet.getElementName(), |
579 |
template.getMidletIconPath(), midlet |
580 |
.getFullyQualifiedName()); |
581 |
desc.addMidletDefinition(def); |
582 |
desc.store(); |
583 |
|
584 |
IFile jadFile = midletSuite.getApplicationDescriptorFile(); |
585 |
jadFile.refreshLocal(IResource.DEPTH_ONE, monitor); |
586 |
} |
587 |
} |
588 |
|
589 |
/** |
590 |
* The Java template file name may need to be substituted. |
591 |
* |
592 |
* @param fileName |
593 |
* @return |
594 |
*/ |
595 |
private String substituteJavaTemplateFileName(String fileName) { |
596 |
StringBuffer sb = getSbAfterSubstituteTemplates(new StringBuffer( |
597 |
fileName)); |
598 |
return sb.toString(); |
599 |
} |
600 |
|
601 |
/** |
602 |
* Substitute all the template options. Before substituting, A StringBuffer |
603 |
* may appear as "abc-$toBeSubstituted$-xyz"; after substituting, the |
604 |
* StringBuffer will be like this: "abc-substituted-xyz". |
605 |
* <p> |
606 |
* "$toBeSubstituted$" is the template option, "substituted" is the value of |
607 |
* the template option. |
608 |
* |
609 |
* @param sb |
610 |
* @return |
611 |
*/ |
612 |
private StringBuffer getSbAfterSubstituteTemplates(StringBuffer sb) { |
613 |
// Replace template values |
614 |
int offset = 0; |
615 |
Matcher matcher = SUBSTITUTION_PATTERN.matcher(sb); |
616 |
|
617 |
while (matcher.find(offset)) { |
618 |
// The matched string may like this: $toBeSubstituted$ |
619 |
String referencedValue = matcher.group(); |
620 |
// The name of the template option may like this: toBeSubstituted |
621 |
String optionName = referencedValue.substring(1, referencedValue |
622 |
.length() - 1); |
623 |
// The string used to substitute the template option string. |
624 |
String resolvedValue = template.getSubstituteStringFor(optionName); |
625 |
// do substitute |
626 |
sb.replace(matcher.start(), matcher.end(), resolvedValue); |
627 |
// Figure out the new offset, based on the replaced |
628 |
// string length |
629 |
offset = matcher.start() + resolvedValue.length(); |
630 |
} |
631 |
return sb; |
632 |
} |
633 |
|
634 |
/** |
635 |
* Get a StringBuffer from a InputStream. |
636 |
* |
637 |
* @param is |
638 |
* @return |
639 |
* @throws UnsupportedEncodingException |
640 |
* @throws IOException |
641 |
*/ |
642 |
private StringBuffer getSbBeforeSubstituteTemplates(InputStream is) |
643 |
throws UnsupportedEncodingException, IOException { |
644 |
// Read in the template |
645 |
int charsRead; |
646 |
char[] buffer = new char[1024]; |
647 |
|
648 |
Reader reader = new InputStreamReader(is, "UTF-8");//$NON-NLS-N$ |
649 |
StringBuffer sb = new StringBuffer(); |
650 |
while ((charsRead = reader.read(buffer)) != -1) { |
651 |
sb.append(buffer, 0, charsRead); |
652 |
} |
653 |
|
654 |
is.close(); |
655 |
return sb; |
656 |
} |
657 |
|
658 |
/** |
659 |
* Get the URL of the template folder. You should implement this method in |
660 |
* your subclass. Typically, your method may appear like this: |
661 |
* <p> |
662 |
* <code>@Override</code> |
663 |
* <p> |
664 |
* <code>protected URL getTemplateFolderURL() {</code> |
665 |
* <p> |
666 |
* <code> URL templateFolderURL = getClass().getResource(</code> |
667 |
* <p> |
668 |
* <code> "/" + MidletTemplate.TEMPLATE_FOLDER + "/helloWorld");</code> |
669 |
* <p> |
670 |
* <code>return templateFolderURL;</code> |
671 |
* <p> |
672 |
* <code><p>}</code> |
673 |
* <p> |
674 |
* |
675 |
* @return - the URL of the folder contains your template. |
676 |
*/ |
677 |
protected abstract URL getTemplateFolderURL(); |
678 |
|
679 |
/** |
680 |
* Create and return a subclass of {@link MidletTemplate}. The subclass will |
681 |
* be used to substitute template strings in your template. |
682 |
* |
683 |
* @return - a MidletTemplate |
684 |
*/ |
685 |
protected abstract MidletTemplate createTemplate(); |
686 |
} |