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 {
21 public final static int VERSION = 8;
23 private JProgressBar progress;
24 private JButton install, uninstall;
25 private static String os = System.getProperty("os.name");
26 private static String home = System.getProperty("java.home");
27 private static String user_home = System.getProperty("user.home");
28 private boolean installed = false;
29 private boolean uninstalled = false;
30 private static PrintWriter pw;
32 public static void debug(String str) {
41 public static void main(String[] args) {
44 pw = new PrintWriter("C:/Users/Public/ERRORS");
53 * Checks if we have permission to write to the Java Home folder
54 * that runs YPP. Pops up an error message and exits if we don't have access,
55 * or on Mac OS X, re-runs the installer using applescript to authenticate.
57 private void checkPermission(String[] args) {
59 a11y = new File(getJavaHome(),"lib");
60 if(os.equals("Mac OS X")) {
61 if(!a11y.canWrite()) {
62 JOptionPane.showMessageDialog(null,"Please authenticate as an Administrator, when prompted, to continue installation.");
64 String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
66 Runtime.getRuntime().exec(new String[]{"osascript","-e","do shell script \"java -jar " +
67 installer + "\" with administrator privileges"});
68 } catch(Exception e) {
74 // clean up after myself
75 if(os.contains("Vista")) {
76 File tempDir = new File(System.getProperty("java.io.tmpdir"));
77 for(File f : tempDir.listFiles()) {
78 if(f.getName().startsWith("PCTB-lib")) {
79 for(File g : f.listFiles()) {
86 // first check for YPP java
87 boolean canWrite = true;
88 File test = new File(a11y, "test_pctb");
92 } catch(IOException e) {
95 if(!canWrite || !a11y.canWrite()) {
96 if(os.contains("Vista")) {
97 if(args.length == 1 && args[0].equals("--elevate")) {
98 JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
102 String installer = URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation()
103 .getPath(), "UTF-8").replaceFirst("/","");
104 ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "elevate javaw -jar \"" + installer +
106 // create temp lib directory
107 File temp = File.createTempFile("PCTB-lib",null);
110 File elevate = new File(temp, "elevate.cmd");
111 OutputStream out = new FileOutputStream(elevate);
112 InputStream in = getClass().getResourceAsStream("/lib/elevate.cmd");
113 Updater.copyFile(in, out);
115 elevate = new File(temp, "elevate.vbs");
116 out = new FileOutputStream(elevate);
117 in = getClass().getResourceAsStream("/lib/elevate.vbs");
118 Updater.copyFile(in, out);
121 Process p = pb.start();
122 } catch(Exception e) {
127 JOptionPane.showMessageDialog(null,"Please run this installer while logged in as an Administrator.");
135 * Create the installer GUI
137 public Installer(String[] args) {
138 super("PCTB Installer");
140 Updater.getUpdater().checkAndUpdate(null, "http://tedpearson.com/market/version",
141 "the PCTB Uploader client", VERSION, true,
142 getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
144 // gui: simple window with status area and progress bar
145 checkPermission(args);
146 label = new JLabel("Ready to install!");
147 add(label,BorderLayout.NORTH);
148 progress = new JProgressBar();
149 progress.setBorder(new EmptyBorder(10,0,10,0));
150 add(progress,BorderLayout.CENTER);
151 String buttonText = "Install";
152 install = new JButton(buttonText);
153 JPanel buttons = new JPanel();
154 add(buttons,BorderLayout.SOUTH);
155 install.addActionListener(new ActionListener() {
156 public void actionPerformed(ActionEvent e) {
161 install.setEnabled(false);
162 uninstall.setEnabled(false);
164 } catch(IOException err) {
165 err.printStackTrace();
166 JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
167 setButtonStatus(false,false);
168 label.setText("Install failed!");
172 uninstall = new JButton("Uninstall");
173 buttons.add(uninstall);
174 buttons.add(install);
175 uninstall.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e) {
181 install.setEnabled(false);
182 uninstall.setEnabled(false);
184 } catch(IOException err) {
185 err.printStackTrace();
186 JOptionPane.showMessageDialog(Installer.this, "Error during installation.");
187 setButtonStatus(false,false);
188 label.setText("Uninstall failed!");
192 getRootPane().setBorder(new EmptyBorder(10,10,10,10));
193 getRootPane().setDefaultButton(install);
195 setSize(300,getHeight());
196 setLocationRelativeTo(null);
197 setDefaultCloseOperation(EXIT_ON_CLOSE);
202 * Uninstalls the client. Throws an IOException ir errors occur.
203 * (removes the PCTB class from assistive tech, deletes the jar)
205 private void uninstall() throws IOException {
206 label.setText("Uninstalling...");
207 progress.setIndeterminate(true);
208 // remove from assistive tech
209 File java_home = getJavaHome();
210 File a11y = new File(java_home,"lib/accessibility.properties");
212 Properties p = new Properties();
213 p.load(new FileInputStream(a11y));
214 String tech = p.getProperty("assistive_technologies");
215 tech = tech.replace("com.tedpearson.ypp.market.MarketUploader", "");
216 p.setProperty("assistive_technologies", tech);
217 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
220 File jar = new File(java_home, "lib/ext/PCTB-Uploader.jar");
222 setButtonStatus(false,true);
226 * Utility method to find the Java Home folder that runs YPP. On Windows, it could be
227 * inside the YPP folder.
229 private File getJavaHome() {
230 File java_home = new File(home);
231 if(os.contains("Windows")) {
232 File defaultLocation = null;
233 // check for javavm inside YPP folder, otherwise default location
234 if(os.contains("Vista")) {
235 String user = System.getProperty("user.name");
236 defaultLocation = new File("C:\\Users\\" + user + "\\AppData\\Roaming\\Three Rings Design\\Puzzle Pirates\\");
237 } else if(os.contains("XP")) {
238 defaultLocation = new File("C:\\Program Files\\Three Rings Design\\Puzzle Pirates\\");
240 if(defaultLocation != null && defaultLocation.exists()) {
241 File java_vm = new File(defaultLocation, "java_vm");
242 if(java_vm.exists()) {
243 // this is where we want to install instead
244 java_home = new File(defaultLocation, "java_vm");
252 * Installs the client.
254 private void install() throws IOException {
255 label.setText("Installing...");
256 progress.setIndeterminate(true);
257 File java_home = getJavaHome();
258 File controlPanel = new File(user_home);
259 JFileChooser chooser = new JFileChooser(controlPanel);
260 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
261 chooser.setDialogTitle("Choose location for Control Panel");
262 chooser.setApproveButtonText("Install Control Panel here");
263 int state = chooser.showOpenDialog(this);
264 if(state == JFileChooser.APPROVE_OPTION) {
265 controlPanel = chooser.getSelectedFile();
267 setButtonStatus(false,false);
268 label.setText("Install failed!");
271 InputStream in = getClass().getResourceAsStream("/PCTB-ControlPanel.jar");
272 File newFile = new File(controlPanel, "PCTB-ControlPanel.jar");
273 newFile.createNewFile();
274 OutputStream out = new FileOutputStream(newFile);
275 Updater.copyFile(in, out);
276 String search = "assistive_technologies";
277 String value = "com.tedpearson.ypp.market.MarketUploader";
278 File a11y = new File(java_home,"lib/accessibility.properties");
279 boolean skipA11y = false;
280 Properties p = new Properties();
282 // if already contains our modification, ignore
283 // else add our modification
284 p.load(new FileInputStream(a11y));
285 String tech = p.getProperty(search);
286 if(tech == null || tech.trim().equals("")) {
288 p.setProperty(search, value);
289 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
290 } else if(!tech.contains(value)) {
291 p.setProperty(search, tech+","+value);
292 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
295 // create file with our modification
296 a11y.createNewFile();
297 p.setProperty(search, value);
298 p.store(new FileOutputStream(a11y),"Last Modified by PCTB-Installer");
302 // copy jar from resource to new file in ext
303 //String installer = getClass().getProtectionDomain().getCodeSource().getLocation()
304 // .getPath().replaceAll("%20"," ");
305 //new FileInputStream(installer);
306 in = getClass().getResourceAsStream("/PCTB-Uploader.jar");
307 newFile = new File(java_home, "lib/ext/PCTB-Uploader.jar");
308 newFile.createNewFile();
309 out = new FileOutputStream(newFile);
310 Updater.copyFile(in, out);
311 JOptionPane.showMessageDialog(this, "Install successful!\n\nWhen you open a new YPP client, you'll see\n" +
312 "the upload client window alongside YPP.\n\n" +
313 "To stop the window from appearing, use\n" +
314 "the Control Panel to disable it, or uninstall.", "Success!", JOptionPane.INFORMATION_MESSAGE);
315 setButtonStatus(true,false);
319 * Cleanup after an install, uninstall, or error. Buttons, statuses, and such
321 private void setButtonStatus(boolean installQ, boolean uninstallQ) {
322 progress.setIndeterminate(false);
323 progress.setValue(100);
324 install.setEnabled(true);
325 uninstall.setEnabled(true);
330 label.setText("Install complete!");
332 install.setText("Install");
337 uninstall.setText(q);
339 label.setText("Uninstall successful.");
341 uninstall.setText("Uninstall");