/******************************************************************************* * Copyright (c) 2007, 2011 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.history.impl; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; import org.simantics.databoard.Bindings; import org.simantics.databoard.accessor.StreamAccessor; import org.simantics.databoard.accessor.error.AccessorException; import org.simantics.databoard.accessor.impl.AccessorParams; import org.simantics.databoard.accessor.java.JavaArray; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.impl.ArrayListBinding; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.Bean; import org.simantics.history.HistoryException; import org.simantics.history.HistoryManager; public class MemoryHistory implements HistoryManager { Map items = new HashMap(); /** Logger */ static Logger logger = Logger.getLogger( MemoryHistory.class.getName() ); @Override public void create(Bean... descs) throws HistoryException { for (Bean desc : descs) { try { String id = (String) desc.getField("id"); Datatype format = (Datatype) desc.getField("format"); Binding sampleBinding = Bindings.getBinding( format ); ArrayListBinding arrayBinding = new ArrayListBinding( sampleBinding ); ArrayList array = new ArrayList(); JavaArray sa = new JavaArray(null, arrayBinding, array, AccessorParams.DEFAULT ); Item item = new Item(); item.stream = sa; item.desc = desc.clone(); item.format = format; items.put(id, item); } catch (BindingException e) { throw new HistoryException("Invalid history item description", e); } } } @Override public void delete(String... itemIds) throws HistoryException { for (String itemId : itemIds) { try { Item i = items.remove( itemId ); if (i==null) throw new HistoryException("Null item"); i.stream.close(); } catch (AccessorException e) { throw new HistoryException(); } } } @Override public void modify(Bean... descs) throws HistoryException { for (Bean desc : descs) { try { String id = (String) desc.getField("id"); Item i = items.get( id ); if ( i == null ) { create(desc); } else { if (desc.equalContents(i.desc)) continue; Datatype format = (Datatype) desc.getField("format"); if (!i.format.equals(format)) { throw new HistoryException("Format conversion is not supported"); } // Write new metadata bean //i.desc = desc.clone(); // Workaround clone -- we cannot clone referable records ( as there is no adaptation context ) try { byte[] data = desc.serialize(); i.desc = desc.getClass().newInstance(); i.desc.deserialize(data); } catch (IOException e) { throw new HistoryException(e); } catch (InstantiationException e) { throw new HistoryException(e); } catch (IllegalAccessException e) { throw new HistoryException(e); } } } catch (BindingException e) { throw new HistoryException(e); } } } @Override public Bean getItem(String itemId) throws HistoryException { Item i = items.get( itemId ); if ( i==null ) throw new HistoryException(itemId+" does not exist"); return i.desc; } @Override public Bean[] getItems() throws HistoryException { Bean[] result = new Bean[ items.size() ]; int ix=0; for (Item i : items.values()) result[ix++] = i.desc; return result; } @Override public void close() { } @Override public StreamAccessor openStream(String itemId, String mode) throws HistoryException { Item i = items.get(itemId); if ( i == null ) { throw new HistoryException(itemId+" does not exist"); } return i.stream; } @Override public synchronized boolean exists(String itemId) throws HistoryException { return items.containsKey(itemId); } static class Item { JavaArray stream; Bean desc; Datatype format; } }