1 package com.tedpearson.ypp.market;
5 import java.awt.event.*;
6 import javax.swing.border.*;
8 import com.tedpearson.util.update.*;
9 import java.util.Properties;
10 import java.net.URLDecoder;
13 allow adding islands/oceans
14 implement uploads to YAARG
18 * An Installer for PCTB Java Client.
20 public class Installer extends JFrame {
22 private JProgressBar progress;
23 private JButton install, uninstall;
24 private static String os = System.getProperty("os.name");
25 private static String home = System.getProperty("java.home");
26 private static String user_home = System.getProperty("user.home");
27 private boolean installed = false;
28 private boolean uninstalled = false;
29 private static PrintWriter pw;
31 public static void debug(String str) {
40 public static void main(String[] args) {
43 pw = new PrintWriter("C:/Users/Public/ERRORS");
52 * Checks if we have permission to write to the Java Home folder
53 * that runs YPP. Pops up an error message and exits if we don't have access,
54 * or on Mac OS X, re-runs the installer using applescript to authenticate.
56 private void checkPermission(String[] args) {
58 a11y = new File(getJavaHome(),"lib");
59 if(os.equals("Mac OS X")) {
60 if(!a11y.canWrite()) {
61 JOptionPane.showMessageDialog(null,"Please authenticate as an Administrator, when prompted, to continue installation.");
63 String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
65 Runtime.getRuntime().exec(new String[]{"osascript","-e","do shell script \"java -jar " +
66 installer + "\" with administrator privileges"});
67 } catch(Exception e) {
73 // clean up after myself
74 if(os.contains("Vista")) {
75 File tempDir = new File(System.getProperty("java.io.tmpdir"));
76 for(File f : tempDir.listFiles()) {
77 if(f.getName().startsWith("PCTB-lib")) {
78 for(File g : f.listFiles()) {
85 // first check for YPP java
86 boolean canWrite = true;
87 File test = new File(a11y, "test_pctb");
91 } catch(IOException e) {
94 if(!canWrite || !a11y.canWrite()) {
95 if(os.contains("Vista")) {
96 if(args.length == 1 && args[0].equals("--elevate")) {
97 JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
101 String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
102 .getPath(), "UTF-8").replaceFirst("/","");
103 ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "elevate javaw -jar \"" + installer +
105 // create temp lib directory
106 File temp = File.createTempFile("PCTB-lib",null);
109 File elevate = new File(temp, "elevate.cmd");
110 OutputStream out = new FileOutputStream(elevate);
111 InputStream in = getClass().getResourceAsStream("/lib/elevate.cmd");
112 Updater.copyFile(in, out);
114 elevate = new File(temp, "elevate.vbs");
115 out = new FileOutputStream(elevate);
116 in = getClass().getResourceAsStream("/lib/elevate.vbs");
117 Updater.copyFile(in, out);
120 Process p = pb.start();
121 } catch(Exception e) {
126 JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
134 * Create the installer GUI
136 public Installer(String[] args) {
137 super("PCTB Installer");
139 // gui: simple window with status area and progress bar
140 checkPermission(args);
141 label = new JLabel("Ready to install!");
142 add(label,BorderLayout.NORTH);
143 progress = new JProgressBar();
144 progress.setBorder(new EmptyBorder(10,0,10,0));
145 add(progress,BorderLayout.CENTER);
146 String buttonText = "Install";
147 install = new JButton(buttonText);
148 JPanel buttons = new JPanel();
149 add(buttons,BorderLayout.SOUTH);
150 install.addActionListener(new ActionListener() {
151 public void actionPerformed(ActionEvent e) {
156 install.setEnabled(false);
157 uninstall.setEnabled(false);
159 } catch(IOException err) {
160 err.printStackTrace();
161 JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
162 setButtonStatus(false,false);
163 label.setText("Install failed!");
167 uninstall = new JButton("Uninstall");
168 buttons.add(uninstall);
169 buttons.add(install);
170 uninstall.addActionListener(new ActionListener() {
171 public void actionPerformed(ActionEvent e) {
176 install.setEnabled(false);
177 uninstall.setEnabled(false);
179 } catch(IOException err) {
180 err.printStackTrace();
181 JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
182 setButtonStatus(false,false);
183 label.setText("Uninstall failed!");
187 getRootPane().setBorder(new EmptyBorder(10,10,10,10));
188 getRootPane().setDefaultButton(install);
190 setSize(300,getHeight());
191 setLocationRelativeTo(null);
192 setDefaultCloseOperation(EXIT_ON_CLOSE);
197 * Uninstalls the client. Throws an IOException ir errors occur.
198 * (removes the PCTB class from assistive tech, deletes the jar)
200 private void uninstall() throws IOException {
201 label.setText("Uninstalling...");
202 progress.setIndeterminate(true);
203 // remove from assistive tech
204 File java_home = getJavaHome();
205 File a11y = new File(java_home,"lib/accessibility.properties");
207 Properties p = new Properties();
208 p.load(new FileInputStream(a11y));
209 String tech = p.getProperty("assistive_technologies");
210 tech = tech.replace("com.tedpearson.ypp.market.MarketUploader", "");
211 p.setProperty("assistive_technologies", tech);
212 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
215 File jar = new File(java_home, "lib/ext/PCTB-Uploader.jar");
217 setButtonStatus(false,true);
221 * Utility method to find the Java Home folder that runs YPP. On Windows, it could be
222 * inside the YPP folder.
224 private File getJavaHome() {
225 File java_home = new File(home);
226 if(os.contains("Windows")) {
227 File defaultLocation = null;
228 // check for javavm inside YPP folder, otherwise default location
229 if(os.contains("Vista")) {
230 String user = System.getProperty("user.name");
231 defaultLocation = new File("C:\\Users\\" + user + "\\AppData\\Roaming\\Three Rings Design\\Puzzle Pirates\\");
232 } else if(os.contains("XP")) {
233 defaultLocation = new File("C:\\Program Files\\Three Rings Design\\Puzzle Pirates\\");
235 if(defaultLocation != null && defaultLocation.exists()) {
236 File java_vm = new File(defaultLocation, "java_vm");
237 if(java_vm.exists()) {
238 // this is where we want to install instead
239 java_home = new File(defaultLocation, "java_vm");
247 * Installs the client.
249 private void install() throws IOException {
250 label.setText("Installing...");
251 progress.setIndeterminate(true);
252 File java_home = getJavaHome();
253 File controlPanel = new File(user_home);
254 JFileChooser chooser = new JFileChooser(controlPanel);
255 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
256 chooser.setDialogTitle("Choose location for Control Panel");
257 chooser.setApproveButtonText("Install Control Panel here");
258 int state = chooser.showOpenDialog(this);
259 if(state == JFileChooser.APPROVE_OPTION) {
260 controlPanel = chooser.getSelectedFile();
262 setButtonStatus(false,false);
263 label.setText("Install failed!");
266 InputStream in = getClass().getResourceAsStream("/PCTB-ControlPanel.jar");
267 File newFile = new File(controlPanel, "PCTB-ControlPanel.jar");
268 newFile.createNewFile();
269 OutputStream out = new FileOutputStream(newFile);
270 Updater.copyFile(in, out);
271 String search = "assistive_technologies";
272 String value = "com.tedpearson.ypp.market.MarketUploader";
273 File a11y = new File(java_home,"lib/accessibility.properties");
274 boolean skipA11y = false;
275 Properties p = new Properties();
277 // if already contains our modification, ignore
278 // else add our modification
279 p.load(new FileInputStream(a11y));
280 String tech = p.getProperty(search);
281 if(tech == null || tech.trim().equals("")) {
283 p.setProperty(search, value);
284 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
285 } else if(!tech.contains(value)) {
286 p.setProperty(search, tech+","+value);
287 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
290 // create file with our modification
291 a11y.createNewFile();
292 p.setProperty(search, value);
293 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
297 // copy jar from resource to new file in ext
298 //String installer = getClass().getProtectionDomain().getCodeSource().getLocation()
299 // .getPath().replaceAll("%20"," ");
300 //new FileInputStream(installer);
301 in = getClass().getResourceAsStream("/PCTB-Uploader.jar");
302 newFile = new File(java_home, "lib/ext/PCTB-Uploader.jar");
303 newFile.createNewFile();
304 out = new FileOutputStream(newFile);
305 Updater.copyFile(in, out);
306 JOptionPane.showMessageDialog(this, "Install successful!\n\nWhen you open a new YPP client, you'll see\n" +
307 "the upload client window alongside YPP.\n\n" +
308 "To stop the window from appearing, use\n" +
309 "the Control Panel to disable it, or uninstall.", "Success!", JOptionPane.INFORMATION_MESSAGE);
310 setButtonStatus(true,false);
314 * Cleanup after an install, uninstall, or error. Buttons, statuses, and such
316 private void setButtonStatus(boolean installQ, boolean uninstallQ) {
317 progress.setIndeterminate(false);
318 progress.setValue(100);
319 install.setEnabled(true);
320 uninstall.setEnabled(true);
325 label.setText("Install complete!");
327 install.setText("Install");
332 uninstall.setText(q);
334 label.setText("Uninstall successful.");
336 uninstall.setText("Uninstall");