Source Code Cross Referenced for JarCreation.java in  » IDE » tIDE » tide » export » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » tIDE » tide.export 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package tide.export;
002:
003:        import javax.swing.JOptionPane;
004:        import snow.utils.SysUtils;
005:        import tide.project.ProjectUtils;
006:        import tide.editor.MainEditorFrame;
007:        import tide.sources.*;
008:        import java.io.*;
009:        import java.util.*;
010:        import snow.utils.storage.*;
011:        import java.util.zip.*;
012:        import java.util.jar.*;
013:
014:        /** Creation of the project jar file, with a lot of associated features.
015:         */
016:        public final class JarCreation {
017:            private JarCreation() {
018:            }
019:
020:            /** Updates the given jar file with all the given files from the source folder (images, .java, ...)
021:             *  @return null if no files are  found.
022:             */
023:            @edu.umd.cs.findbugs.annotations.CheckReturnValue
024:            public static Process addFilesFromSourceFolder(
025:                    final File jarExecutor, final File jarFile,
026:                    final File source_home, boolean includeSourceFiles,
027:                    boolean includeResourceFiles,
028:                    final List<String> ignoredEndings) throws Exception {
029:                if (!jarExecutor.exists())
030:                    throw new Exception("Jar tool no found: " + jarExecutor);
031:
032:                final List<String> execCommand = new ArrayList<String>();
033:                execCommand.add(jarExecutor.getAbsolutePath());
034:                execCommand.add("-J-Xmx512M"); // ?? TODO: offers as parameter OR grew if out of memory detected
035:                execCommand.add("-J-Duser.language=en");
036:                execCommand.add("uvf"); // update !
037:                execCommand.add(jarFile.getAbsolutePath());
038:
039:                final StringBuilder sourceFilesList = new StringBuilder();
040:                int srcLen = FileUtils.getCanonicalName(source_home).length();
041:                if (includeSourceFiles) {
042:                    final List<SourceFile> allSources = MainEditorFrame.instance.sourcesTreePanel
043:                            .getTreeModel().getAllSourceFiles(false); // without ignored
044:                    sl: for (int i = 0; i < allSources.size(); i++) {
045:                        String relName = allSources.get(i).javaFile
046:                                .getAbsolutePath().substring(srcLen);
047:                        sourceFilesList.append("" + relName); // sources names have no spaces (?)
048:                        if (i < allSources.size() - 1)
049:                            sourceFilesList.append("\r\n");
050:                    }
051:                    sourceFilesList.append("\n");
052:                }
053:
054:                if (includeResourceFiles) {
055:                    // all but *.java files and ignored... (resources in ignored source folders are also not in the list)
056:                    final List<File> allResources = MainEditorFrame.instance.sourcesTreePanel
057:                            .getTreeModel().getAllResourceFiles(ignoredEndings);
058:                    for (int i = 0; i < allResources.size(); i++) {
059:                        String relName = allResources.get(i).getAbsolutePath()
060:                                .substring(srcLen).trim();
061:                        if (relName.indexOf(' ') > 0) {
062:                            relName = "\"" + relName.replace("\\", "/") + "\""; // important !, quote + replace \\ with / !
063:                            System.out
064:                                    .println("Jar resource name with spaces: "
065:                                            + relName);
066:                        }
067:                        sourceFilesList.append("" + relName);
068:
069:                        if (i < allResources.size() - 1)
070:                            sourceFilesList.append("\r\n");
071:                    }
072:                    sourceFilesList.append("\n");
073:                }
074:
075:                if (sourceFilesList.length() < 2)
076:                    return null; // [Oct2007]
077:
078:                final File sourcesListFile = new File(source_home
079:                        .getAbsolutePath(), "sources_to_jar");
080:                sourcesListFile.deleteOnExit();
081:                FileUtils.saveToFile(sourceFilesList.toString(),
082:                        sourcesListFile);
083:
084:                execCommand.add("-C");
085:                execCommand.add(source_home.getAbsolutePath());
086:                // not working well... java.util.zip.ZipException: duplicate entry: aaa/
087:                execCommand.add("@" + sourcesListFile.getAbsolutePath());
088:
089:                MainEditorFrame
090:                        .debugOut("Create jar file (add sources and/or resources)\n"
091:                                + "Command = " + execCommand);
092:
093:                ProcessBuilder pb = new ProcessBuilder(execCommand);
094:                pb.directory(source_home); // must be started in the source dir !!
095:                Process proc = pb.start();
096:
097:                return proc;
098:            }
099:
100:            /** @param customManifestFile is null (normal case), a correct and complete manif will be created
101:             * Don't include classes excluded from project !
102:             * ( they are also not compiled => not in the classes folder )
103:             *   => project must be cleared and compiled first.
104:             */
105:            public static Process createClassesJarFile(File jarExecutor,
106:                    File jarFile, File classesDest, String mainClassName,
107:                    List<File> classPath, File customManifestFile)
108:                    throws Exception {
109:                if (!jarExecutor.exists())
110:                    throw new Exception("Jar tool no found: " + jarExecutor);
111:
112:                // Manifest
113:                //
114:                File manifestFile = null;
115:                if (customManifestFile == null) {
116:                    StringBuilder manifest = new StringBuilder(
117:                            "Manifest-Version: 1.0\nCreated-By: "
118:                                    + System.getProperty("java.version",
119:                                            "1.6.0_05") + " ("
120:                                    + MainEditorFrame._VERSION + ")");
121:
122:                    if (mainClassName != null && mainClassName.length() > 0) {
123:                        manifest.append("\nMain-Class: " + mainClassName);
124:                    }
125:
126:                    if (classPath.size() > 0) {
127:                        manifest.append("\nClass-Path: ");
128:                        for (int i = 0; i < classPath.size(); i++) {
129:                            manifest.append("" + classPath.get(i).getName()); // [April2006]: names instead of full path...  (not valid to have absolute paths !!)
130:                            if (i < classPath.size() - 1)
131:                                manifest.append("  "); // Two spaces !! one is the continuation char !!
132:                        }
133:                    }
134:                    manifest.append("\n"); // IMPORTANT !!
135:
136:                    manifestFile = File.createTempFile("Manifest", null);
137:                    manifestFile.deleteOnExit();
138:                    FileUtils.saveToFile(manifest.toString(), manifestFile);
139:                } else {
140:                    manifestFile = customManifestFile;
141:
142:                    if (!manifestFile.exists())
143:                        throw new RuntimeException(
144:                                "The given custom manifest file doesn't exist: "
145:                                        + manifestFile);
146:
147:                    String cont = FileUtils.getFileStringContent(manifestFile);
148:                    if (!cont.endsWith("\n")) {
149:                        //Todo: ask to fix ?
150:                        throw new Exception(
151:                                "The manifest file MUST end with a blank line (return)");
152:                    }
153:                    manifestFile = customManifestFile;
154:                }
155:
156:                List<String> execCommand = new ArrayList<String>();
157:                execCommand.add(jarExecutor.getAbsolutePath());
158:                execCommand.add("-J-Xmx512M"); // ??
159:                execCommand.add("-J-Duser.language=en"); // [March2007]: tide outputs are in english.
160:                execCommand.add("cvmf");
161:                execCommand.add(manifestFile.getAbsolutePath());
162:                execCommand.add(jarFile.getAbsolutePath());
163:
164:                // ToDO: also can be made with an argument file
165:                execCommand.add("-C");
166:                execCommand.add(classesDest.getAbsolutePath());
167:                // Thanks Mike K. for the bugix.
168:                execCommand.add("."); // linux accept only this, windows both "." and "*"
169:
170:                MainEditorFrame
171:                        .debugOut("Create jar file (classes)\nCommand = "
172:                                + execCommand);
173:
174:                ProcessBuilder pb = new ProcessBuilder(execCommand);
175:                pb.directory(classesDest);
176:                return pb.start();
177:            }
178:
179:            /** A small batch launcher to start the jar app with the JVM arguments
180:             *   ( A double click on a jar will ignore them... [Jan2006] ).
181:             */
182:            public static void createBatchLauncher(File javaExecutor,
183:                    File jarFile, String jvmOptions, String appOptions)
184:                    throws Exception {
185:
186:                File dest = (SysUtils.is_Windows_OS() ? new File(jarFile
187:                        .getAbsolutePath()
188:                        + ".bat") : new File(jarFile.getAbsolutePath() + ".sh"));
189:                StringBuilder bf = new StringBuilder();
190:                if (!SysUtils.is_Windows_OS()) {
191:                    bf.append("#/bin/sh\n"); // NOT \r\n !!
192:                }
193:                String jp = javaExecutor.getAbsolutePath();
194:                if (jp.indexOf(' ') > 0)
195:                    bf.append("\""); // also linux ?
196:                bf.append(jp);
197:                if (jp.indexOf(' ') > 0)
198:                    bf.append("\"");
199:
200:                if (jvmOptions.trim().length() > 0) {
201:                    bf.append(" " + jvmOptions);
202:                }
203:                bf.append(" -jar \"" + jarFile.getAbsolutePath() + "\"");
204:                if (appOptions.trim().length() > 0) {
205:                    bf.append(" " + appOptions);
206:                }
207:
208:                if (!SysUtils.is_Windows_OS()) {
209:                    bf.append(" $*"); // allow passing any arguments
210:                }
211:
212:                FileUtils.saveToFile(bf.toString(), dest);
213:
214:                if (!SysUtils.is_Windows_OS()) {
215:                    // chmod +x dest
216:                    //SysUtils.wri
217:                    try {
218:                        dest.setExecutable(true, false); // for all users
219:                    } catch (Exception e) {
220:                        JOptionPane
221:                                .showMessageDialog(
222:                                        null,
223:                                        "Can't set execute flag for the launch script\n\n   "
224:                                                + dest
225:                                                + "\n\nPlease set it in a shell with the command \"sudo chmod +x "
226:                                                + dest.getName() + "\"",
227:                                        "Warning", JOptionPane.WARNING_MESSAGE);
228:                    }
229:                }
230:            }
231:
232:            /** A jnlp launcher to start the jar through the net.
233:             * Overtakes most settings from the project, as classpath, main method, ...
234:             * app arguments, jvm arguments (not all are supported, be careful !)
235:             */
236:            public static void createJNLPLauncher(
237:                    File jarFile,
238:                    String jvmOptions, // TODO...  (problem: not all options are available...)
239:                    String appOptions, String mainClassJavaName,
240:                    List<File> classPath, String codeBase, String title,
241:                    String vendor, String homepage, String descr,
242:                    String j2seversion, String xmx, // deprecated : replaced ba jvmOptions !
243:                    boolean isSigned) throws Exception {
244:
245:                if (mainClassJavaName == null
246:                        || mainClassJavaName.trim().length() == 0) {
247:                    throw new Exception(
248:                            "The project must contain a valid main class name, otherwise no JNLP can be created."
249:                                    + "\n(Nothing to launch !).");
250:                }
251:
252:                String fname = jarFile.getAbsolutePath();
253:                String fnameBase = fname.substring(0, fname.length() - 4);
254:                fname = fnameBase + ".jnlp";
255:                File dest = new File(fname);
256:                File icon = new File(fnameBase + ".png");
257:
258:                StringBuilder bf = new StringBuilder(
259:                        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!-- JNLP File Created with tIDE  -->\r\n<jnlp spec=\"1.0+\"");
260:                bf.append("\r\n    codebase=\"" + codeBase + "\"");
261:                bf.append("\r\n    href=\"" + dest.getName() + "\">");
262:                bf.append("\r\n  <information>");
263:                bf.append("\r\n     <title>" + title + "</title>");
264:                bf.append("\r\n     <vendor>" + vendor + "</vendor>");
265:                bf.append("\r\n     <homepage href=\"" + homepage + "\"/>");
266:                bf.append("\r\n     <description>" + descr + "</description>");
267:                bf.append("\r\n     <description kind=\"short\">" + descr
268:                        + "</description>");
269:                bf.append("\r\n     <icon href=\"" + icon.getName() + "\"/>");
270:                bf.append("\r\n     <offline-allowed/>");
271:                bf.append("\r\n  </information>");
272:                bf.append("\r\n  <security>");
273:                if (isSigned) {
274:                    bf.append("\r\n     <all-permissions/>");
275:                }
276:                bf.append("\r\n  </security>");
277:                bf.append("\r\n  <resources>");
278:                bf.append("\r\n    <j2se version=\"" + j2seversion + "\"");
279:                if (xmx != null && xmx.length() > 0) {
280:                    bf.append(" max-heap-size=\"" + xmx + "\"");
281:                }
282:                if (jvmOptions != null && jvmOptions.length() > 0) {
283:                    bf.append(" java-vm-args=\"" + jvmOptions + "\"");
284:                }
285:                bf.append("/>");
286:                bf.append("\r\n    <jar href=\"" + jarFile.getName() + "\"/>");
287:                // add project class path files !
288:                // They must also be exported (manually) and signed with the same key as the main jar !
289:                if (classPath != null) {
290:                    for (File cpf : classPath) {
291:                        bf.append("\r\n    <jar href=\"" + cpf.getName()
292:                                + "\"/>");
293:                    }
294:                }
295:                bf.append("\r\n  </resources>");
296:                bf.append("\r\n  <application-desc main-class=\""
297:                        + mainClassJavaName + "\">");
298:                // arguments
299:                if (appOptions != null && appOptions.trim().length() > 0) {
300:                    for (final String apo : ProjectUtils.splitArgs(appOptions,
301:                            false)) {
302:                        bf.append("\r\n    <argument>\"" + apo
303:                                + "\"</argument>");
304:                    }
305:                }
306:
307:                bf.append("\r\n  </application-desc>");
308:                bf.append("\r\n</jnlp>");
309:                FileUtils.saveToFile(bf.toString(), dest);
310:            }
311:
312:            /** Since 1.3, create an index (incomplete ! ?) of the jar and the jars in the class-path.
313:             *  Important: the files to index are prsent in the classpath manifest entry and MUST be present
314:             *  in the destination folder (where the jar is)
315:             */
316:            public static Process indexJarFile(File jarExecutor, File jarFile)
317:                    throws Exception {
318:                if (!jarExecutor.exists())
319:                    throw new Exception("Jar tool no found: " + jarExecutor);
320:
321:                List<String> execCommand = new ArrayList<String>();
322:                execCommand.add(jarExecutor.getAbsolutePath());
323:                execCommand.add("-J-Duser.language=en");
324:                execCommand.add("i");
325:                execCommand.add("\"" + jarFile.getAbsolutePath() + "\""); // MUST BE QUOTED ! because of "program files"
326:
327:                MainEditorFrame.debugOut("indexing jar files: " + execCommand);
328:
329:                ProcessBuilder pb = new ProcessBuilder(execCommand);
330:                pb.directory(jarFile.getParentFile());
331:                return pb.start();
332:            }
333:
334:            /** pack200 and gzipped, => very good compression success... 5 to 9 on pure class contents!
335:             *  Be careful, the signature is NOT conservated, because pack200
336:             *  let a great freedom for the reconstruction, some variable tables may be shuffled !
337:             *  and sha-1 and other bytecode verifications are no more of same signature !!!
338:             *  => normalize the jar before signing !
339:             *
340:             * PROBLEM: uses JVM memory and causes problems... => call in another JVM !
341:             */
342:            @SuppressWarnings("unchecked")
343:            public static void compress_pack200(File src, File dest)
344:                    throws Exception {
345:                Pack200.Packer packer = Pack200.newPacker();
346:
347:                // Initialize the state by setting the desired properties
348:                Map p = packer.properties();
349:                // take more time choosing codings for better compression
350:                p.put(Pack200.Packer.EFFORT, "7"); // default is "5"
351:                // use largest-possible archive segments (>10% better compression).
352:                p.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
353:                // reorder files for better compression.
354:                p.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.FALSE);
355:                // smear modification times to a single value.
356:                p.put(Pack200.Packer.MODIFICATION_TIME, Pack200.Packer.LATEST);
357:                // ignore all JAR deflation requests,
358:                // transmitting a single request to use "store" mode.
359:                p.put(Pack200.Packer.DEFLATE_HINT, Pack200.Packer.FALSE);
360:                // discard debug attributes
361:                p.put(Pack200.Packer.CODE_ATTRIBUTE_PFX + "LineNumberTable",
362:                        Pack200.Packer.STRIP);
363:                // throw an error if an attribute is unrecognized
364:                p.put(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.ERROR);
365:
366:                FileOutputStream fos = null;
367:                try {
368:                    JarFile jarFile = new JarFile(src);
369:                    fos = new FileOutputStream(dest);
370:                    GZIPOutputStream gos = new GZIPOutputStream(fos);
371:                    // Call the packer
372:                    packer.pack(jarFile, gos);
373:                    jarFile.close();
374:                    gos.flush();
375:                    gos.close();
376:
377:                    /*System.out.println("Pack200 results: ");
378:                    System.out.println("  Before:   \tjar file length="+src.length()+" bytes");
379:                    System.out.println("  After:     \tjar file length="+dest.length()+" bytes");*/
380:                } catch (Exception e) {
381:                    e.printStackTrace();
382:                    throw e;
383:                } finally {
384:                    FileUtils.closeIgnoringExceptions(fos);
385:                }
386:            }
387:
388:            /**
389:             *  Pack200 rearranges the contents of the resultant JAR file. The jarsigner hashes the contents of the class file
390:             *  and stores the hash in an encrypted digest in the manifest. When the unpacker runs on a packed packed, the contents
391:             *  of the classes will be rearranged and thus invalidate the signature. Therefore, the JAR file must be normalized first
392:             *  using pack200 and unpack200, and thereafter signed.
393:             * [Nov2007] Could be also made with "pack200 --repack myarchive.jar"
394:             *
395:             * (Here's why this works: Any reordering the packer does of any classfile structures is idempotent, so the second packing
396:             * does not change the orderings produced by the first packing. Also, the unpacker is guaranteed by the JSR 200 specification
397:             * to produce a specific bytewise image for any given transmission ordering of archive elements.)
398:             */
399:            @SuppressWarnings("unchecked")
400:            public static void replaceJarWithPack200Decompressed(File jarFile,
401:                    File pack200GzFile) throws Exception {
402:                File tmpDest = File.createTempFile("tide_" + jarFile.getName(),
403:                        null);
404:                tmpDest.deleteOnExit();
405:                FileOutputStream fostream = null;
406:                JarOutputStream jostream = null;
407:                FileInputStream fis = null;
408:
409:                try {
410:                    fostream = new FileOutputStream(tmpDest);
411:                    jostream = new JarOutputStream(fostream);
412:
413:                    Pack200.Unpacker unpacker = Pack200.newUnpacker();
414:                    Map p = unpacker.properties();
415:                    p.put(Pack200.Unpacker.DEFLATE_HINT, Pack200.Unpacker.TRUE);
416:
417:                    fis = new FileInputStream(pack200GzFile);
418:                    GZIPInputStream gis = new GZIPInputStream(fis);
419:
420:                    unpacker.unpack(gis, jostream);
421:
422:                    // Must explicitly close the output.
423:                    jostream.close();
424:                    fis.close();
425:
426:                    // ok, it worked => replace the files
427:                    if (jarFile.exists()) {
428:                        if (!jarFile.delete()) {
429:                            throw new Exception("Cannot delete " + jarFile);
430:                        }
431:                    }
432:                } catch (Exception e) {
433:                    throw e;
434:                } finally {
435:                    FileUtils.closeIgnoringExceptions(fis);
436:                    FileUtils.closeIgnoringExceptions(fostream);
437:                }
438:
439:                long lm = tmpDest.lastModified();
440:
441:                //tmpDest.renameTo(jarFile);  //thanks Mike K. suggering that this is not good for example if on diff partitions
442:                FileUtils.copy(tmpDest, jarFile);
443:
444:                // overtake the date. this is necessary because this function is also used by the updater.
445:                jarFile.setLastModified(lm);
446:            }
447:
448:            /** To retrieve all the sources, use<pre>
449:             *    List<SourceFile> allSources = MainEditorFrame.instance.sourcesTreePanel.getTreeModel().getAllSourceFiles();</pre>
450:             */
451:            public static void create_separate_SourcesZipFile(
452:                    File sources_home, List<SourceFile> allSources,
453:                    List<File> resources, File dest) throws Exception {
454:                if (!dest.getParentFile().exists()) {
455:                    dest.getParentFile().mkdirs();
456:                }
457:
458:                FileOutputStream fos = null;
459:                ZipOutputStream zos = null;
460:                try {
461:                    fos = new FileOutputStream(dest);
462:                    zos = new ZipOutputStream(fos);
463:
464:                    int srcLen = FileUtils.getCanonicalName(sources_home)
465:                            .length();
466:
467:                    sl: for (int i = 0; i < allSources.size(); i++) {
468:                        if (allSources.get(i).isIgnored())
469:                            continue sl;
470:
471:                        String relName = allSources.get(i).javaFile
472:                                .getAbsolutePath().substring(srcLen);
473:                        relName = "src/" + relName.replace("\\", "/");
474:                        FileUtils.addToZip(zos, allSources.get(i).javaFile,
475:                                relName);
476:                    }
477:
478:                    if (resources != null) {
479:                        for (File rfi : resources) {
480:                            String relName = rfi.getAbsolutePath().substring(
481:                                    srcLen);
482:                            relName = "src/" + relName.replace("\\", "/");
483:                            FileUtils.addToZip(zos, rfi, relName);
484:                        }
485:                    }
486:                } catch (Exception e) {
487:                    throw e;
488:                } finally {
489:                    FileUtils.closeIgnoringExceptions(zos);
490:                    FileUtils.closeIgnoringExceptions(fos);
491:                }
492:            }
493:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.