/* * @(#)SerializationStorageFormat.java * * Project: JHotdraw - a GUI framework for technical drawings * http://www.jhotdraw.org * http://jhotdraw.sourceforge.net * Copyright: © by the original author(s) and all contributors * License: Lesser GNU Public License (LGPL) * http://www.opensource.org/licenses/lgpl-license.html */ package CH.ifa.draw.util; import CH.ifa.draw.framework.*; import CH.ifa.draw.standard.StandardDrawing; import java.io.*; import java.util.*; import java.util.List; import java.awt.*; import javax.jdo.*; import javax.swing.*; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; /** * @author Wolfram Kaiser * @version <$CURRENT_VERSION$> */ public class JDOStorageFormat extends StandardStorageFormat { private Map pms; /** * Create a SerialzationStorageFormat for storing and restoring Drawings. */ public JDOStorageFormat() { super(); pms = CollectionsFactory.current().createMap(); // close database connection when application exits Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { Iterator iter = pms.values().iterator(); // while (iter.hasNext()) { // ((PersistenceManager)iter.next()).close(); // } } }); } /** * Factory method to create the file extension recognized by the FileFilter for this * SerializationStorageFormat. The SerializationStorageFormat has the file extension "ser" * (e.g. my_picasso.ser). * * @return new file extension */ protected String createFileExtension() { return "j2"; } /** * Factory method to create a file description for the file type when displaying the * associated FileFilter. * * @return new file description */ public String createFileDescription() { return "Database (" + getFileExtension() + ")"; } /** * @see CH.ifa.draw.util.StorageFormat#isRestoreFormat() */ public boolean isRestoreFormat() { return true; } /** * @see CH.ifa.draw.util.StorageFormat#isStoreFormat() */ public boolean isStoreFormat() { return true; } /** * Store a Drawing under a given name. The name should be valid with regard to the FileFilter * that means, it should already contain the appropriate file extension. * * @param fileName file name of the Drawing under which it should be stored * @param storeDrawing drawing to be saved */ public String store(String fileName, Drawing storeDrawing) throws IOException { PersistenceManager pm = getPersistenceManager(fileName); String drawingName = null; Drawing txnDrawing = crossTxnBoundaries(storeDrawing); endTransaction(pm, false); startTransaction(pm); try { Extent extent = pm.getExtent(StandardDrawing.class, true); DrawingListModel listModel = new DrawingListModel(extent.iterator()); drawingName = showStoreDialog(listModel, storeDrawing); if (drawingName != null) { storeDrawing.setTitle(drawingName); txnDrawing.setTitle(drawingName); pm.makePersistent(txnDrawing); } } finally { endTransaction(pm, (drawingName != null)); } // there must be always a transaction running startTransaction(pm); return drawingName; } /** * Restore a Drawing from a file with a given name. The name must be should with regard to the * FileFilter that means, it should have the appropriate file extension. * * @param fileName of the file in which the Drawing has been saved * @return restored Drawing */ public synchronized Drawing restore(String fileName) throws IOException { PersistenceManager pm = getPersistenceManager(fileName); endTransaction(pm, false); startTransaction(pm); Drawing restoredDrawing = null; try { Extent extent = pm.getExtent(StandardDrawing.class, true); DrawingListModel listModel = new DrawingListModel(extent.iterator()); Drawing txnDrawing = showRestoreDialog(listModel); if (txnDrawing != null) { // pm.retrieve(txnDrawing); // retrieveAll(pm, (StandardDrawing)txnDrawing); // restoredDrawing = crossTxnBoundaries(txnDrawing); restoredDrawing = txnDrawing; } } finally { endTransaction(pm, false); } // there must be always a transaction running startTransaction(pm); return restoredDrawing; } private void retrieveAll(PersistenceManager pm, Figure figure) { pm.retrieve(figure); FigureEnumeration fe = figure.figures(); while (fe.hasNextFigure()) { retrieveAll(pm, fe.nextFigure()); } } private Drawing crossTxnBoundaries(Drawing originalDrawing) { return (Drawing)((StandardDrawing)originalDrawing).clone(); // return originalDrawing; } private synchronized PersistenceManager getPersistenceManager(String fileName) { PersistenceManager pm = (PersistenceManager)pms.get(fileName); if (pm == null) { pm = createPersistenceManagerFactory(fileName).getPersistenceManager(); pms.put(fileName, pm); } return pm; } private PersistenceManagerFactory createPersistenceManagerFactory(String dbFileName) { Properties pmfProps = new Properties(); pmfProps.put( "javax.jdo.PersistenceManagerFactoryClass", "com.poet.jdo.PersistenceManagerFactories" ); pmfProps.put( "javax.jdo.option.ConnectionURL", "fastobjects://LOCAL/MyBase.j1" ); final PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory( pmfProps ); return pmf; } private static void startTransaction(PersistenceManager pm) { if (!pm.currentTransaction().isActive()) { pm.currentTransaction().begin(); } } private static void endTransaction(PersistenceManager pm, boolean doCommit) { if (pm.currentTransaction().isActive()) { if (doCommit) { pm.currentTransaction().commit(); } else { pm.currentTransaction().rollback(); } } } private String showStoreDialog(ListModel listModel, Drawing storeDrawing) { final String msgString = "Specify a name for the drawing"; final JTextField nameTextField = new JTextField(storeDrawing.getTitle()); final JList dataList = new JList(listModel); final JScrollPane dbContentScrollPane = new JScrollPane(dataList); Object[] guiComponents = {msgString, dbContentScrollPane, nameTextField}; dataList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); dataList.setValueIsAdjusting(true); dataList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { nameTextField.setText(dataList.getSelectedValue().toString()); } }); final JOptionPane optionPane = new JOptionPane( guiComponents, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); final JDialog dialog = optionPane.createDialog(null, "Restore a drawing from the database"); // dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); // dialog.addWindowListener(new WindowAdapter() { // public void windowClosing(WindowEvent we) { // System.exit(0); // } // }); dialog.setVisible(true); if ((optionPane.getValue() != null) && (optionPane.getValue().equals(new Integer(JOptionPane.OK_OPTION)))) { return nameTextField.getText(); } else { return null; } } private Drawing showRestoreDialog(DrawingListModel listModel) { final String msgString = "Select a drawing"; final JList dataList = new JList(listModel); final JScrollPane dbContentScrollPane = new JScrollPane(dataList); Object[] guiComponents = {msgString, dbContentScrollPane}; dataList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); dataList.setValueIsAdjusting(true); final JOptionPane optionPane = new JOptionPane( guiComponents, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); final JDialog dialog = optionPane.createDialog(null, "Restore a drawing from the database"); dialog.setVisible(true); if ((optionPane.getValue() != null) && (optionPane.getValue().equals(new Integer(JOptionPane.OK_OPTION))) && (dataList.getSelectedIndex() >= 0) && (dataList.getSelectedIndex() < dataList.getModel().getSize())) { return listModel.getDrawingAt(dataList.getSelectedIndex()); } else { return null; } } static class DrawingListModel extends AbstractListModel { private List myList; DrawingListModel(Iterator iter) { myList = CollectionsFactory.current().createList(); while (iter.hasNext()) { Object o = iter.next(); System.out.println("extent: " + o + " .. " + ((Drawing)o).getTitle()); myList.add(o); } } public Object getElementAt(int index) { return getDrawingAt(index).getTitle(); } protected Drawing getDrawingAt(int index) { return ((Drawing)myList.get(index)); } public int getSize() { return myList.size(); } } static class DrawingSelector extends JDialog { DrawingSelector() { init(); } private void init() { setTitle("Select Drawing"); getContentPane().setLayout(new BorderLayout()); getContentPane().add(new JLabel("Database content"), BorderLayout.NORTH); setSize(200, 200); } } public static void main(String[] args) { DrawingSelector frame = new DrawingSelector(); try { Drawing newDrawing = new StandardDrawing(); newDrawing.setTitle("TestDrawingName" + new Random(System.currentTimeMillis()).nextLong()); new JDOStorageFormat().store("base.j2", newDrawing); System.exit(0); } catch (IOException e) { e.printStackTrace(); } // frame.setVisible(true); } }