/* * Copyright (C) 2014 Shashank Tulsyan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package neembuu.release1.open; import neembuu.release1.api.open.Opener; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import jpfm.SystemUtils; import neembuu.release1.app.Application; import neembuu.release1.api.open.Open; import neembuu.release1.api.open.OpenerAccess; import neembuu.release1.api.ui.MainComponent; import neembuu.release1.pismo.lin; import neembuu.util.Throwables; /** * * @author Shashank Tulsyan */ public final class OpenerImpl implements Opener { private final Map<String,Open> openHandles = new HashMap<>(); private final MainComponent mainComponent; public OpenerImpl(MainComponent mainComponent) { this.mainComponent = mainComponent; } private final OpenerAccess openerA = new OpenerAccess() { @Override public void closeAll() { OpenerImpl.this.closeAllImpl(); } @Override public Open openHandles_remove(String filePath) { return OpenerImpl.this.openHandles.remove(filePath); } }; private void closeAllImpl(){ // this complexity is to avoid concurrent modification exception // closing all instances, includes ones which on close // remove themselves from the list of open handles Open[]openHandlerArr = openHandles.values().toArray(new Open[0]); for(Open o : openHandlerArr){ o.closeAll(); } // closing zombie open handles which for some odd reason didn't remove // their copies for(Open o : openHandles.values()){ System.out.println("Closing zombie open handle -> "+o); try{ o.closeAll(); }catch(Exception a){ a.printStackTrace(); } } openHandles.clear(); } public final OpenerAccess getOpenerAccess() { return openerA; } @Override public Open open(String fileToOpen){ Open x = openHandles.get(fileToOpen); if(x!=null){ x.close(); } if(SystemUtils.IS_OS_WINDOWS){ return openWin(fileToOpen); }else if(SystemUtils.IS_OS_MAC){ return fallBackOpen(fileToOpen); }else { return openLin(fileToOpen); } } @Override public Open openFolder(String f)throws Exception{ if(!new File(f).isDirectory())throw new IllegalArgumentException(f+" is not a directory"); if(SystemUtils.IS_OS_WINDOWS){ return openFolderWin(f); }else if(SystemUtils.IS_OS_MAC){ return fallbackOpenFolder(f); }else { return fallbackOpenFolder(f); } } private Open openFolderWin(String fileToOpen)throws Exception{ ProcessBuilder pb = new ProcessBuilder("explorer.exe",fileToOpen); Process p = null; try{ p = pb.start(); }catch(Exception a){ throw a; } OpenImplWindowFolder oi = new OpenImplWindowFolder(p, fileToOpen, openerA); openHandles.put(fileToOpen, oi); return oi; } private Open fallbackOpenFolder(String f)throws Exception{ java.awt.Desktop.getDesktop().open(new File(f)); return DummyOpen.I(); } private Open openWin(String absoluteFilePath) { Path vlc = Application.getResource(Application.Resource.Installation,"vlc"); vlc = vlc.resolve("vlc-1.1.11-win32").resolve("vlc.exe"); if(Files.exists(vlc)){ return make(vlc, absoluteFilePath);} else { vlc = Paths.get(System.getenv("ProgramFiles"),"VideoLAN","VLC","vlc.exe"); if(Files.exists(vlc)){ return make(vlc, absoluteFilePath);} else { vlc = Paths.get("C:","Program Files (x86)","VideoLAN","VLC","vlc.exe"); if(Files.exists(vlc)){ return make(vlc, absoluteFilePath);} else { vlc = Paths.get("C:","Program Files","VideoLAN","VLC","vlc.exe"); if(Files.exists(vlc)){ return make(vlc, absoluteFilePath);} else { return fallBackOpen(absoluteFilePath); } } } } } private Open openLin(String f) { Path vlc = Paths.get("/usr/bin/vlc"); if(Files.exists(vlc)){ return make(vlc, f); }else { Throwables.start(new Runnable(){ @Override public void run() { askLinUserToInstallVLC(); } },"Install VLC thread"); }return fallBackOpen(f); } private void askLinUserToInstallVLC(){ boolean u = mainComponent.newMessage().setTitle("VLC not found") .setMessage("VLC is one of the most suited video players\n" + "for use with Neembuu. Other players might also work" + "very well.\n" + "Should Neembuu attempt to install vlc?") .ask(); if(!u)return; String cmd = "sudo apt-get -y install vlc"; String password = mainComponent.newMessage().setTitle("Please enter super user root password") .setMessage("To install VLC, the following command will be executed\n" + cmd) .askPassword(); if(password==null)return; String out = lin.executeAsRoot(password, cmd, mainComponent); } private Open fallBackOpen(String absoulteFilePath){ try{ java.awt.Desktop.getDesktop().open(new File(absoulteFilePath)); return DummyOpen.I(); }catch(Exception ioe){ try{ java.awt.Desktop.getDesktop().open(new File(absoulteFilePath).getParentFile()); }catch(Exception ioe1){ mainComponent.newMessage().error().setTitle("Could not open file") .setMessage(absoulteFilePath).setTimeout(10000).showNonBlocking(); ioe.printStackTrace(); ioe1.printStackTrace(); } }return DummyOpen.I(); } private Open make(Path vlc, String fileToOpen){ vlc = vlc.toAbsolutePath(); ProcessBuilder pb = new ProcessBuilder(vlc.toString(),fileToOpen); Process p = null; try{ p = pb.start(); }catch(Exception a){ return fallBackOpen(fileToOpen); } OpenImpl oi = new OpenImpl(p, fileToOpen, openerA); openHandles.put(fileToOpen, oi); return oi; } }