Installer.java
 1 /**
 2  * @author Qbix
 3  * Application responsible for installing another application
 4  * folder Install contains files to copy regardless of install options
 5  * folder Optional contains groups of optionaly installing files
 6  * i.e.
 7  * Optional
 8  *  Language
 9  *   pl
10  *    files to install
11  *   en
12  *    ...
13  *  Location
14  *   Poland
15  *    ...
16  *   United States
17  *    ...
18  */
19 
20 package installer;
21 
22 import java.io.BufferedOutputStream;
23 import java.io.File;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.util.Enumeration;
29 import java.util.Hashtable;
30 import java.util.jar.JarEntry;
31 import java.util.jar.JarFile;
32 
33 public class Installer {
34     String srcPath;                     //path of JarFile
35     String destPath;                    //path of destination directory
36     Hashtable<String, String> options;  //options used for optional instalation stored as <Folder, Subfolder>
37     JarFile source;                     //sourcefile as JarFile
38     public Installer(String srcPath, Hashtable<String, String> options, String destPath) throws IOException{
39         this.destPath = destPath;
40         this.srcPath = srcPath;
41         this.options = options;
42         source = new JarFile(this.srcPath);
43         Enumeration<JarEntry> entries = source.entries();
44         while(entries.hasMoreElements()){
45             JarEntry entry = entries.nextElement();
46             String[] splitedEntry = entry.getName().split("/");
47             //if it's standard instalation file, copy in any case
48             if(splitedEntry[0].equals("Install") && splitedEntry.length>1){
49                 executeCopy(entry, stripSlashes(entry.getName(), 1));
50             }
51             //if it's optional file - check it's category and criteria from it
52             if(splitedEntry[0].equals("Optional") && splitedEntry.length>3 && !options.isEmpty()){
53                 if(options.containsKey(splitedEntry[1])){
54                     if(options.get(splitedEntry[1]).equals(splitedEntry[2])){
55                         executeCopy(entry, stripSlashes(entry.getName(), 3));
56                     }
57                 }
58             }
59         }
60     }
61     //responsible for copying files to specified folder
62     public void executeCopy(JarEntry entry, String destInnerPath) throws IOException{
63         File parent = new File(destPath);
64         if(!parent.exists()) parent.mkdirs();
65         if(entry.isDirectory()){
66             System.out.println("Creating directory: " + destPath + "/" + destInnerPath);
67             (new File(destPath + "/" + destInnerPath)).mkdir();
68         }
69         else{
70             System.out.println("Creating file: " + destPath + "/" + destInnerPath);
71             copyInputStream(source.getInputStream(entry), new BufferedOutputStream(new FileOutputStream(destPath + "/" + destInnerPath)));
72         }
73     }
74     //responsible for copying body of files between them
75     public static final void copyInputStream(InputStream in, OutputStream out) throws IOException
76     {
77         byte[] buffer = new byte[1024];
78         int len;
79 
80         while((len = in.read(buffer)) >= 0)
81           out.write(buffer, 0, len);
82 
83         in.close();
84         out.close();
85     }
86     //simple helper for strip the begining of inner path needed for stripping Install/ and Optional/x/y/
87     public static final String stripSlashes(String input, int count){
88         int index = input.indexOf("/");
89         while(count > 0 && index!=-1){
90             input = input.substring(index + 1);
91             index = input.indexOf("/");
92             count --;
93         }
94         return input;
95     }
96 }
97 
98