/* * 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.mountmanager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.util.logging.Level; import java.util.logging.Logger; import jpfm.FormatterEvent; import jpfm.JPfm; import jpfm.MountListener; import jpfm.fs.SimpleReadOnlyFileSystem; import jpfm.mount.Mount; import jpfm.mount.MountParams; import jpfm.mount.MountParamsBuilder; import jpfm.mount.Mounts; import jpfm.volume.CommonFileAttributesProvider; import jpfm.volume.vector.VectorRootDirectory; import neembuu.diskmanager.DiskManager; import neembuu.release1.app.Application; import neembuu.release1.api.RealFileProvider; import neembuu.release1.api.log.LoggerUtil; import neembuu.release1.api.open.Openers; import neembuu.release1.api.ui.IndefiniteTaskUI; import neembuu.release1.api.ui.MainComponent; import neembuu.release1.api.ui.Message; import neembuu.release1.api.ui.access.MinimalistFileSystem; import neembuu.release1.api.ui.access.MainUIA; import neembuu.release1.pismo.PismoInstaller; import neembuu.vfs.file.TroubleHandler; import org.shashaank.utils.jni.ClassScope; /** * * @author Shashank Tulsyan */ public final class MountManager { private Mount mount; private JPfm.Manager manager = null; private final VectorRootDirectory volume; private final SimpleReadOnlyFileSystem fs; private final MainComponent mainComponent; private final IndefiniteTaskUI indefiniteTaskUI; private final MainUIA mainUIA; private final TroubleHandler troubleHandler; private final DiskManager diskManager; private final MinimalistFileSystem minimalistFileSystem; private static final Logger L = LoggerUtil.getLogger(MountManager.class.getName()); public MountManager(MainComponent mainComponent, IndefiniteTaskUI indefiniteTaskUI, MainUIA mainUIA, TroubleHandler troubleHandler, DiskManager diskManager) { this.mainComponent = mainComponent; this.indefiniteTaskUI = indefiniteTaskUI; this.mainUIA = mainUIA; this.troubleHandler = troubleHandler; this.diskManager = diskManager; volume = new VectorRootDirectory(10, 3,CommonFileAttributesProvider.DEFAULT); fs = new SimpleReadOnlyFileSystem(volume); minimalistFileSystem = new MinimalistFileSystem_Root(volume,troubleHandler, diskManager,realFileProvider,fs); } public Mount getMount() { return mount; } public SimpleReadOnlyFileSystem getFileSystem() { return fs; } public VectorRootDirectory getRootDirectory(){ return volume; } public void initialize(){ try{ mount = mount(0, Application.getResource(Application.Resource.VirtualFolderMountLocation)); }catch(Exception a){ L.log(Level.SEVERE,"Could not create NeembuuVirtualFolder",a); mainComponent.newMessage().error() .setMessage("Could not initialize Java pismo file mount\n"+ "Pismo file mount might not be installed.\n"+ "Actual error message="+a.getMessage()) .setTitle("Error in initialize JPfm") .setEmotion(Message.Emotion.I_AM_DEAD) .show(); System.exit(-1); } } private static boolean excelsiorRuntime(){ String k = System.getProperty("runningexcelsior"); if(k==null)return false; return k.equalsIgnoreCase("true"); } private Mount mount(int attempt, Path mntLoc) throws Exception { Mount m = null; boolean retry = true;// false; if (attempt >= 0) { //1 for testing //0 for release try { manager = JPfm.setDefaultManager(LoggerUtil.getLogger("JPfm.Manager")); printListOfNativeLibrariesLoaded(); m = Mounts.mount(new MountParamsBuilder() .set(MountParams.ParamType.MOUNT_LOCATION, mntLoc) .set(MountParams.ParamType.FILE_SYSTEM, fs) .set(MountParams.ParamType.LISTENER, new MountListener() { @Override public void eventOccurred(FormatterEvent event) { mountEventReceived(event); } }).build()); } catch (NullPointerException ne) { L.log(Level.SEVERE, "NullPointerException while test mounting", ne); Throwable e = JPfm.getLastException(); if (e != null) { L.log(Level.SEVERE, "", e); if (e.getMessage().equalsIgnoreCase("Pismo file mount incorrectly installed or not installed")) { retry = true; } } } } if (m != null) { return m; } if (retry) { if (attempt < 2) { // TODO : show a gui message informing user that Pismo is being // installed PismoInstaller.tryInstallingPismoFileMount(mainComponent,false, new ICBL(mainComponent, indefiniteTaskUI)); return mount(attempt + 1, mntLoc); } } throw new RuntimeException("Neither can use pismo file mount nor can install it. Retried " + attempt + " time(s)"); } private void printListOfNativeLibrariesLoaded(){ try{ final String[] libraries = ClassScope.getLoadedLibraries(ClassLoader.getSystemClassLoader()); String res = "==================Native Libraries loaded=============\n"; for (int i = 0; i < libraries.length; i++) { res += libraries[i]+"\n"; } res+="==================Native Libraries loaded============="; L.info(res); }catch(Exception a){ L.log(Level.INFO,"Could not print list of native libraries",a); } try{ for (java.util.logging.Handler h : L.getHandlers()) { h.flush(); } }catch(Exception a){} } int c = 0; private void mountEventReceived(FormatterEvent event){ checkDetached(event); if(c>0)return; c++; addHelpFile(); mainUIA.neembuuVirtualFolderButton().setEnabled(true); mainUIA.neembuuVirtualFolderButton().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("executing="+e); openVirtualFolder(); } }); } private void checkDetached(FormatterEvent event){ if(event.getEventType()==FormatterEvent.EVENT.DETACHED){ if(!event.getMessage().contains("external"))return; mainComponent.getJFrame().setVisible(false); mainComponent.getJFrame().setVisible(true); mainComponent.newMessage() .setTitle("Virtual folder externally unmounted") .setMessage("Some external tool might have initiated an\n" + "unmount operation or and error might have occurred.\n" + "\n" + "The application is going to exit.") .setTimeout(10000) .show(); System.exit(-1); } } private void openVirtualFolder(){ String fileToOpen = ""; try{ File f = getMount().getMountLocation().getAsFile(); fileToOpen = f.getAbsolutePath(); Openers.I().openFolder(fileToOpen); }catch(Exception a){ L.log(Level.SEVERE,"Could not open NeembuuFolder",a); mainComponent.newMessage().error() .setMessage(fileToOpen + "\n.Reason : " + "\n"+a.getMessage()) .setTitle("Could not open virtual folder ") .show(); } } private void addHelpFile(){ // The file name and file contents should respect local language Path helpFile = Application.getResource(Application.Resource.Installation, "help","Getting started.pdf"); try { if(!Files.exists(helpFile))return; if(!Files.isRegularFile(helpFile))return; jpfm.volume.RealFile rf = jpfm.volume.RealFileProvider.getNonBlockingRealFile(helpFile.toAbsolutePath().toString(), volume); volume.add(rf); } catch (Exception e) { L.log(Level.SEVERE,"Could not put help file in virtual folder",e); } } private final RealFileProvider realFileProvider = new RealFileProvider() { @Override public File getRealFile(String... relativePathInVirtualFileSystem) { String pth=getMount().getMountLocation().toString(); for (String stringPath : relativePathInVirtualFileSystem) { pth+=(File.separatorChar+stringPath); }return new File(pth); } }; public final RealFileProvider getRealFileProvider() { return realFileProvider; } public final MinimalistFileSystem getMinimalistFileSystem() { return minimalistFileSystem; } }