/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.apps.jpartition.model; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.jnode.apps.jpartition.Context; import org.jnode.apps.jpartition.commands.CreatePartitionCommand; import org.jnode.apps.jpartition.commands.FormatPartitionCommand; import org.jnode.apps.jpartition.commands.RemovePartitionCommand; import org.jnode.apps.jpartition.commands.framework.Command; import org.jnode.apps.jpartition.commands.framework.CommandProcessor; import org.jnode.apps.jpartition.commands.framework.CommandProcessorListener; import org.jnode.driver.bus.ide.IDEDevice; import org.jnode.fs.FileSystem; import org.jnode.fs.Formatter; import org.jnode.fs.ext2.BlockSize; import org.jnode.fs.ext2.Ext2FileSystemFormatter; import org.jnode.fs.fat.FatFileSystemFormatter; import org.jnode.fs.fat.FatType; import org.jnode.fs.jfat.ClusterSize; public class UserFacade { private static final Logger LOG = Logger.getLogger(UserFacade.class); static { LOG.setLevel(Level.DEBUG); } private static final UserFacade INSTANCE = new UserFacade(); private final Map<String, Device> devices = new HashMap<String, Device>(); private Device selectedDevice; private UserListener userListener; private final Map<String, Formatter<? extends FileSystem<?>>> formatters = new HashMap<String, Formatter<? extends FileSystem<?>>>(); private Formatter<? extends FileSystem<?>> selectedFormatter; private Context context; private CommandProcessor cmdProcessor; public static UserFacade getInstance() { return INSTANCE; } private UserFacade() { refreshDevicesFromOS(); addFormatter(new FatFileSystemFormatter(FatType.FAT32)); addFormatter(new org.jnode.fs.jfat.FatFileSystemFormatter(ClusterSize._16Kb)); addFormatter(new Ext2FileSystemFormatter(BlockSize._4Kb)); } public void setContext(Context context) { this.context = context; cmdProcessor = new CommandProcessor(context); } public void selectFormatter(String name) { selectedFormatter = formatters.get(name); } public void selectDevice(String name) { selectDevice(name, false); // called by the user => no need to notify } public Device getSelectedDevice() { return selectedDevice; } private void selectDevice(String name, boolean notify) { selectedDevice = devices.get(name); if (notify && (userListener != null)) { userListener.selectionChanged(selectedDevice); } } public void setUserListener(UserListener listener) { this.userListener = listener; OSListener osListener = new OSListener() { public void deviceAdded(Device addedDevice) { devices.put(addedDevice.getName(), addedDevice); userListener.deviceAdded(addedDevice.getName()); } public void deviceRemoved(Device removedDevice) { devices.remove(removedDevice.getName()); userListener.deviceRemoved(removedDevice.getName()); if ((selectedDevice != null) && selectedDevice.equals(removedDevice)) { // not called by user => need to notify selectDevice(null, true); } } public void errorHappened(OSFacadeException e) { if (context.getErrorReporter() != null) { context.getErrorReporter().reportError(LOG, UserFacade.this, e); } } }; try { OSFacade.getInstance().setOSListener(osListener); } catch (OSFacadeException e) { osListener.errorHappened(e); } } public void addCommandProcessorListener(CommandProcessorListener listener) { cmdProcessor.addListener(listener); } public String[] getFormatters() { String[] names = formatters.keySet().toArray(new String[formatters.size()]); Arrays.sort(names); return names; } public String[] getDeviceNames() { String[] names = devices.keySet().toArray(new String[devices.size()]); Arrays.sort(names); return names; } public List<Device> getDevices() { List<Device> devs = new ArrayList<Device>(devices.values()); Collections.sort(devs, new Comparator<Device>() { public int compare(Device dev1, Device dev2) { return dev1.getName().compareTo(dev2.getName()); } }); return devs; } public List<Partition> getPartitions() throws Exception { checkSelectedDevice(); return selectedDevice.getPartitions(); } public Partition createPartition(long start, long size) throws Exception { checkSelectedDevice(); Partition newPart = selectedDevice.addPartition(start, size); cmdProcessor.addCommand(new CreatePartitionCommand((IDEDevice) selectedDevice.getDevice(), 0, start, size)); return newPart; } public void removePartition(long offset) throws Exception { checkSelectedDevice(); selectedDevice.removePartition(offset); cmdProcessor.addCommand(new RemovePartitionCommand((IDEDevice) selectedDevice.getDevice(), 0)); // TODO set parameters } public void formatPartition(long offset) throws Exception { checkSelectedDevice(); checkSelectedFormatter(); Formatter<? extends FileSystem<?>> formatter = selectedFormatter.clone(); selectedDevice.formatPartition(offset, formatter); //TODO set parameters Command cmd = new FormatPartitionCommand((IDEDevice) selectedDevice.getDevice(), 0, formatter); cmdProcessor.addCommand(cmd); } public void resizePartition(long offset, long size) throws Exception { checkSelectedDevice(); // selectedDevice.resizePartition(offset, selectedFormatter.clone()); // cmdProcessor.addCommand(new FormatPartitionCommand((IDEDevice) // selectedDevice.getDevice(), 0)); //TODO set parameters } public void applyChanges() { cmdProcessor.process(); refreshDevicesFromOS(); } public List<Command> getPendingCommands() { return cmdProcessor.getPendingCommands(); } private void refreshDevicesFromOS() { devices.clear(); String selectedDev = (selectedDevice == null) ? null : selectedDevice.getName(); try { for (Device device : OSFacade.getInstance().getDevices()) { devices.put(device.getName(), device); } // not called by user => need to notify selectDevice(selectedDev, true); } catch (OSFacadeException e) { if (context.getErrorReporter() != null) { context.getErrorReporter().reportError(LOG, this, e); } } } private void checkSelectedDevice() throws Exception { if (selectedDevice == null) { throw new Exception("no device selected"); } } private void checkSelectedFormatter() throws Exception { if (selectedFormatter == null) { throw new Exception("no formatter selected"); } } private void addFormatter(Formatter<? extends FileSystem<?>> formatter) { formatters.put(formatter.getFileSystemType().getName(), formatter); } }