package nl.fontys.sofa.limo.domain.component; import com.google.gson.Gson; import com.google.gson.annotations.Expose; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import nl.fontys.sofa.limo.domain.component.hub.Hub; import nl.fontys.sofa.limo.domain.component.leg.Leg; import nl.fontys.sofa.limo.domain.component.serialization.GsonHelper; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; /** * Holder of a complete supply chain with actors, hubs, legs and events. Can be * stored to file and recreated from file. * * @author Dominik Kaisers {@literal <d.kaisers@student.fontys.nl>} */ public class SupplyChain implements Serializable { @Expose private static final long serialVersionUID = 1185813427289144002L; @Expose private String name; private transient String filepath = null; /** * The supply chain does only contain the start hub because via the start * hub it can get the complete supply chain due the properties of a * LinkedList. */ @Expose private Hub startHub; private transient static Gson gson; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getFilepath() { return filepath; } public void setFilepath(String filepath) { this.filepath = filepath; } public Hub getStartHub() { return startHub; } public void setStartHub(Hub startHub) { this.startHub = startHub; } /** * Recreates a supply chain stored in the given file. * * @return Recreated supply chain. * @param file The file to open. */ public static SupplyChain createFromFile(File file) { InputStream in = null; try { in = new FileInputStream(file); Gson g = GsonHelper.getInstance(); SupplyChain supplyChain; try (JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"))) { reader.beginArray(); supplyChain = g.fromJson(reader, SupplyChain.class); reader.endArray(); } Node pre = supplyChain.getStartHub(); if (pre != null) { Node act = pre.getNext(); while (act != null) { act.setPrevious(pre); pre = act; act = act.getNext(); } } supplyChain.setFilepath(file.getAbsolutePath()); return supplyChain; } catch (FileNotFoundException | UnsupportedEncodingException ex) { ex.printStackTrace(System.err); } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (Exception ex) { Exceptions.printStackTrace(ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { Exceptions.printStackTrace(ex); } } return null; } /** * Saves the supply chain to a file specified at filepath. * * @param path path where to save the chain * @throws java.io.IOException */ public void saveToFile(String path) throws IOException { OutputStream out = new FileOutputStream(path); Gson g = GsonHelper.getInstance(); FileObject ob = FileUtil.toFileObject(new File(path)); FileLock lock = null; try { lock = ob.lock(); JsonWriter writer = new JsonWriter(new OutputStreamWriter(ob.getOutputStream(lock))); writer.setIndent(" "); writer.beginArray(); g.toJson(this, SupplyChain.class, writer); writer.endArray(); writer.flush(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } finally { if (lock != null) { lock.releaseLock(); } } } public void saveToFile() throws IOException { saveToFile(filepath); } private transient List<PropertyChangeListener> listeners = new ArrayList<>(); public void addListerner(PropertyChangeListener listerner) { listeners.add(listerner); } public void removeListener(PropertyChangeListener listener) { listeners.remove(listener); } public void fireAddHubEvent(Hub node) { PropertyChangeEvent event = new PropertyChangeEvent(this, "ADD_HUB", null, node); fireEvent(event); } public void fireRemoveHubEvent(Hub node) { PropertyChangeEvent event = new PropertyChangeEvent(this, "REMOVE_HUB", node, null); fireEvent(event); } public void fireAddLegEvent(Leg node) { PropertyChangeEvent event = new PropertyChangeEvent(this, "ADD_LEG", null, node); fireEvent(event); } public void fireRemoveLegEvent(Leg node) { PropertyChangeEvent event = new PropertyChangeEvent(this, "REMOVE_LEG", node, null); fireEvent(event); } private void fireEvent(PropertyChangeEvent event) { listeners.parallelStream().forEach((listener) -> { listener.propertyChange(event); }); } }