X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.history%2Fsrc%2Forg%2Fsimantics%2Fhistory%2Fimpl%2FFileHistory.java;fp=bundles%2Forg.simantics.history%2Fsrc%2Forg%2Fsimantics%2Fhistory%2Fimpl%2FFileHistory.java;h=f3169b60673ede3a26bb72ed10b02784d912c300;hp=0ecefd484e88f33b3cea9b1b66298aa8eaf177d3;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.history/src/org/simantics/history/impl/FileHistory.java b/bundles/org.simantics.history/src/org/simantics/history/impl/FileHistory.java index 0ecefd484..f3169b606 100644 --- a/bundles/org.simantics.history/src/org/simantics/history/impl/FileHistory.java +++ b/bundles/org.simantics.history/src/org/simantics/history/impl/FileHistory.java @@ -1,464 +1,464 @@ -/******************************************************************************* - * 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.DataInput; -import java.io.DataOutput; -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -import org.simantics.databoard.Accessors; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.accessor.ArrayAccessor; -import org.simantics.databoard.accessor.StreamAccessor; -import org.simantics.databoard.accessor.error.AccessorConstructionException; -import org.simantics.databoard.accessor.error.AccessorException; -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.adapter.Adapter; -import org.simantics.databoard.adapter.AdapterConstructionException; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; -import org.simantics.databoard.serialization.Serializer; -import org.simantics.databoard.serialization.SerializerConstructionException; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.Component; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.NumberType; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.util.Bean; -import org.simantics.databoard.util.ObjectUtils; -import org.simantics.databoard.util.URIUtil; -import org.simantics.databoard.util.binary.BinaryMemory; -import org.simantics.databoard.util.binary.ByteBufferWriteable; -import org.simantics.history.HistoryException; -import org.simantics.history.HistoryManager; -import org.simantics.utils.FileUtils; - -/** - * File history uses workarea (directory) to manage items. - * There are two files for every item: stream file and metadata file. - * Metadata file is JSON ascii file. - * itemname.data - * itemname.txt - * - * @author toni.kalajainen - * - */ -public class FileHistory implements HistoryManager { - - private static final boolean PROFILE = false; - private static final boolean DEBUG = false; - - /** Logger */ - static Logger logger = Logger.getLogger(FileHistory.class.getName()); - - static FilenameFilter txtFilter; - - static ArrayType INDEX_TYPE = Bindings.LONG_ARRAY.type(); - - File workarea; - - /** Support async usage of the data */ - public boolean asyncUsage = true; - - public FileHistory(File workarea) { - this.workarea = workarea; - } - - public File getWorkarea() { - return workarea; - } - - @Override - public void create(Bean... items) throws HistoryException { - - try { - for (Bean item : items) { - if (DEBUG) - System.out.println("create(" + item + ")"); -// if ( !item.getFieldBinding("format").type().equals( Bindings.getBindingUnchecked(Datatype.class).type() ) ) -// System.err.println("Error"); - - // Write meta data - writeMetadata( item ); - - // Create stream file - String id = (String) item.getField("id"); - File dataFile = toDataFile( id ); - dataFile.createNewFile(); - - Datatype type = (Datatype) item.getField("format"); - if ( isVariableWidth(type) ) { - File indexFile = toIndexFile( id ); - indexFile.createNewFile(); - } -// if ( !dataFile.createNewFile() ) { -// throw new HistoryException("Could not create file "+dataFile); -// } - } - } catch (BindingException e) { - throw new HistoryException(e); - } catch (IOException e) { - throw new HistoryException(e); - } - } - - @Override - public void delete(String... itemIds) throws HistoryException { - for (String itemId : itemIds ) { - File meta = toMetaFile( itemId ); - File data = toDataFile( itemId ); - File index = toIndexFile( itemId ); - if ( meta.exists() ) { - if ( !meta.delete() ) { - throw new HistoryException("Failed to delete "+meta); - } - } - if ( data.exists() ) { - if ( !data.delete() ) { - throw new HistoryException("Failed to delete "+data); - } - } - if ( index.exists() ) { - if ( !index.delete() ); - } - } - } - - @Override - public void modify(Bean... items) throws HistoryException { - - try { - for ( Bean item : items ) { - if (DEBUG) - System.out.println("modify(" + item + ")"); -// if ( !item.getFieldBinding("format").type().equals( Bindings.getBindingUnchecked(Datatype.class).type() ) ) -// System.err.println("Error"); - - String id = (String) item.getField("id"); - File metaFile = toMetaFile( id ); - if ( !metaFile.exists() ) { - create( item ); - } else { - Bean oldItem = getItem( id ); - File dataFile = toDataFile( id ); - if ( dataFile.exists() ) { - boolean enabled = item.hasField("enabled") ? (Boolean) item.getFieldUnchecked("enabled") : true; - Datatype oldFormat = (Datatype) oldItem.getField( "format" ); - Datatype newFormat = (Datatype) item.getField( "format" ); - if (DEBUG) - System.out.println("formats: " + oldFormat + " -> " + newFormat); - Datatype unitStrippedOldFormat = stripUnitAnnotations(oldFormat); - Datatype unitStrippedNewFormat = stripUnitAnnotations(newFormat); - if (DEBUG) - System.out.println("formats after unit strip: " + unitStrippedOldFormat + " -> " + unitStrippedNewFormat); - if ( enabled && !unitStrippedOldFormat.equals(unitStrippedNewFormat) ) { - try { - Binding oldBinding = Bindings.getBeanBinding(unitStrippedOldFormat); - Binding newBinding = Bindings.getBeanBinding(unitStrippedNewFormat); - Serializer oldS = Bindings.getSerializer(oldBinding); - Serializer newS = Bindings.getSerializer(newBinding); - if (oldS.getConstantSize()==null || newS.getConstantSize()==null || oldS.getConstantSize()!=newS.getConstantSize()) - throw new HistoryException("Changing of file format is not supported to: "+dataFile); - Adapter adapter = Bindings.getAdapter(oldBinding, newBinding); - Object oldSample = oldBinding.createDefault(); - Object newSample = newBinding.createDefault(); - StreamAccessor sa = openStream(id, "rw"); - try { - int c = sa.size(); - for (int i=0; i result = new ArrayList(); - File[] files = workarea.listFiles(txtFilter); - if ( files != null ) { - for (File file : files) { - result.add( getItem(file) ); - } - } - return result.toArray( new Bean[ result.size() ] ); - } - - @Override - public void close() { - // Nothing to do. - } - - @Override - public StreamAccessor openStream(String itemId, String mode) throws HistoryException { - try { - Bean bean = getItem(itemId); - Datatype format = (Datatype) bean.getField("format"); - ArrayType arrayType = new ArrayType(format); - File dataFile = toDataFile( itemId ); - if ( isVariableWidth(format) ) { - File indexFile = toIndexFile( itemId ); - ArrayAccessor index = Accessors.openStream(indexFile, INDEX_TYPE, mode); - return (StreamAccessor) Accessors.openStream(dataFile, arrayType, mode, index); - } else { - return (StreamAccessor) Accessors.openStream(dataFile, arrayType, mode); - } - } catch (AccessorConstructionException e) { - throw new HistoryException(e); - } catch (BindingException e) { - throw new HistoryException(e); - } - } - - @Override - public boolean exists(String itemId) throws HistoryException { - return toMetaFile(itemId).exists(); - } - - @Override - public int hashCode() { - return workarea.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if ( obj==null ) return false; - if ( obj instanceof FileHistory == false ) return false; - FileHistory other = (FileHistory) obj; - return other.workarea.equals(workarea); - } - - @Override - public String toString() { - return "FileHistory: "+workarea; - } - - private boolean equalsWithoutState(Bean i1, Bean i2) { - Component[] components1 = i1.getBinding().type().getComponents(); - Component[] components2 = i2.getBinding().type().getComponents(); - int components = Math.min(components1.length, components2.length); - for (int c = 0; c < components; ++c) { - Object o1 = i1.getFieldUnchecked(c); - Object o2 = i2.getFieldUnchecked(c); - if ("collectorState".equals(components1[c].name) && (o1 == null || o2 == null)) - continue; - if (!ObjectUtils.objectEquals(o1, o2)) - return false; - } - return true; - } - - static { - txtFilter = new FilenameFilter() { - public boolean accept(File dir, String name) { - return name.toLowerCase().endsWith(".txt"); - } - }; - } - - private static Datatype stripUnitAnnotations(Datatype datatype) { - if (datatype instanceof NumberType) { - NumberType nt = (NumberType) datatype; - if (nt.getUnit() != null) { - Binding dtb = Bindings.getBindingUnchecked(Datatype.class); - datatype = nt = (NumberType) Bindings.cloneUnchecked(datatype, dtb, dtb); - nt.setUnit(null); - } - } else if (datatype instanceof ArrayType) { - ArrayType at = (ArrayType) datatype; - Datatype ct = at.componentType(); - Datatype component = stripUnitAnnotations(ct); - if (component != ct) { - Binding dtb = Bindings.getBindingUnchecked(Datatype.class); - datatype = at = (ArrayType) Bindings.cloneUnchecked(datatype, dtb, dtb); - at.setComponentType(component); - } - } else if (datatype instanceof RecordType) { - RecordType rt = (RecordType) datatype; - int componentCount = rt.getComponentCount(); - Component[] newComponents = new Component[componentCount]; - for (int i = 0; i < componentCount; ++i) { - Component c = rt.getComponent(i); - Datatype ct = c.type; - Datatype sct = stripUnitAnnotations(ct); - newComponents[i] = new Component(c.name, sct); - } - return new RecordType(rt.isReferable(), newComponents); - } - return datatype; - } - -} +/******************************************************************************* + * 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.DataInput; +import java.io.DataOutput; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.simantics.databoard.Accessors; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.accessor.ArrayAccessor; +import org.simantics.databoard.accessor.StreamAccessor; +import org.simantics.databoard.accessor.error.AccessorConstructionException; +import org.simantics.databoard.accessor.error.AccessorException; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.adapter.Adapter; +import org.simantics.databoard.adapter.AdapterConstructionException; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.serialization.Serializer; +import org.simantics.databoard.serialization.SerializerConstructionException; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.Component; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.NumberType; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.util.Bean; +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.databoard.util.URIUtil; +import org.simantics.databoard.util.binary.BinaryMemory; +import org.simantics.databoard.util.binary.ByteBufferWriteable; +import org.simantics.history.HistoryException; +import org.simantics.history.HistoryManager; +import org.simantics.utils.FileUtils; + +/** + * File history uses workarea (directory) to manage items. + * There are two files for every item: stream file and metadata file. + * Metadata file is JSON ascii file. + * itemname.data + * itemname.txt + * + * @author toni.kalajainen + * + */ +public class FileHistory implements HistoryManager { + + private static final boolean PROFILE = false; + private static final boolean DEBUG = false; + + /** Logger */ + static Logger logger = Logger.getLogger(FileHistory.class.getName()); + + static FilenameFilter txtFilter; + + static ArrayType INDEX_TYPE = Bindings.LONG_ARRAY.type(); + + File workarea; + + /** Support async usage of the data */ + public boolean asyncUsage = true; + + public FileHistory(File workarea) { + this.workarea = workarea; + } + + public File getWorkarea() { + return workarea; + } + + @Override + public void create(Bean... items) throws HistoryException { + + try { + for (Bean item : items) { + if (DEBUG) + System.out.println("create(" + item + ")"); +// if ( !item.getFieldBinding("format").type().equals( Bindings.getBindingUnchecked(Datatype.class).type() ) ) +// System.err.println("Error"); + + // Write meta data + writeMetadata( item ); + + // Create stream file + String id = (String) item.getField("id"); + File dataFile = toDataFile( id ); + dataFile.createNewFile(); + + Datatype type = (Datatype) item.getField("format"); + if ( isVariableWidth(type) ) { + File indexFile = toIndexFile( id ); + indexFile.createNewFile(); + } +// if ( !dataFile.createNewFile() ) { +// throw new HistoryException("Could not create file "+dataFile); +// } + } + } catch (BindingException e) { + throw new HistoryException(e); + } catch (IOException e) { + throw new HistoryException(e); + } + } + + @Override + public void delete(String... itemIds) throws HistoryException { + for (String itemId : itemIds ) { + File meta = toMetaFile( itemId ); + File data = toDataFile( itemId ); + File index = toIndexFile( itemId ); + if ( meta.exists() ) { + if ( !meta.delete() ) { + throw new HistoryException("Failed to delete "+meta); + } + } + if ( data.exists() ) { + if ( !data.delete() ) { + throw new HistoryException("Failed to delete "+data); + } + } + if ( index.exists() ) { + if ( !index.delete() ); + } + } + } + + @Override + public void modify(Bean... items) throws HistoryException { + + try { + for ( Bean item : items ) { + if (DEBUG) + System.out.println("modify(" + item + ")"); +// if ( !item.getFieldBinding("format").type().equals( Bindings.getBindingUnchecked(Datatype.class).type() ) ) +// System.err.println("Error"); + + String id = (String) item.getField("id"); + File metaFile = toMetaFile( id ); + if ( !metaFile.exists() ) { + create( item ); + } else { + Bean oldItem = getItem( id ); + File dataFile = toDataFile( id ); + if ( dataFile.exists() ) { + boolean enabled = item.hasField("enabled") ? (Boolean) item.getFieldUnchecked("enabled") : true; + Datatype oldFormat = (Datatype) oldItem.getField( "format" ); + Datatype newFormat = (Datatype) item.getField( "format" ); + if (DEBUG) + System.out.println("formats: " + oldFormat + " -> " + newFormat); + Datatype unitStrippedOldFormat = stripUnitAnnotations(oldFormat); + Datatype unitStrippedNewFormat = stripUnitAnnotations(newFormat); + if (DEBUG) + System.out.println("formats after unit strip: " + unitStrippedOldFormat + " -> " + unitStrippedNewFormat); + if ( enabled && !unitStrippedOldFormat.equals(unitStrippedNewFormat) ) { + try { + Binding oldBinding = Bindings.getBeanBinding(unitStrippedOldFormat); + Binding newBinding = Bindings.getBeanBinding(unitStrippedNewFormat); + Serializer oldS = Bindings.getSerializer(oldBinding); + Serializer newS = Bindings.getSerializer(newBinding); + if (oldS.getConstantSize()==null || newS.getConstantSize()==null || oldS.getConstantSize()!=newS.getConstantSize()) + throw new HistoryException("Changing of file format is not supported to: "+dataFile); + Adapter adapter = Bindings.getAdapter(oldBinding, newBinding); + Object oldSample = oldBinding.createDefault(); + Object newSample = newBinding.createDefault(); + StreamAccessor sa = openStream(id, "rw"); + try { + int c = sa.size(); + for (int i=0; i result = new ArrayList(); + File[] files = workarea.listFiles(txtFilter); + if ( files != null ) { + for (File file : files) { + result.add( getItem(file) ); + } + } + return result.toArray( new Bean[ result.size() ] ); + } + + @Override + public void close() { + // Nothing to do. + } + + @Override + public StreamAccessor openStream(String itemId, String mode) throws HistoryException { + try { + Bean bean = getItem(itemId); + Datatype format = (Datatype) bean.getField("format"); + ArrayType arrayType = new ArrayType(format); + File dataFile = toDataFile( itemId ); + if ( isVariableWidth(format) ) { + File indexFile = toIndexFile( itemId ); + ArrayAccessor index = Accessors.openStream(indexFile, INDEX_TYPE, mode); + return (StreamAccessor) Accessors.openStream(dataFile, arrayType, mode, index); + } else { + return (StreamAccessor) Accessors.openStream(dataFile, arrayType, mode); + } + } catch (AccessorConstructionException e) { + throw new HistoryException(e); + } catch (BindingException e) { + throw new HistoryException(e); + } + } + + @Override + public boolean exists(String itemId) throws HistoryException { + return toMetaFile(itemId).exists(); + } + + @Override + public int hashCode() { + return workarea.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if ( obj==null ) return false; + if ( obj instanceof FileHistory == false ) return false; + FileHistory other = (FileHistory) obj; + return other.workarea.equals(workarea); + } + + @Override + public String toString() { + return "FileHistory: "+workarea; + } + + private boolean equalsWithoutState(Bean i1, Bean i2) { + Component[] components1 = i1.getBinding().type().getComponents(); + Component[] components2 = i2.getBinding().type().getComponents(); + int components = Math.min(components1.length, components2.length); + for (int c = 0; c < components; ++c) { + Object o1 = i1.getFieldUnchecked(c); + Object o2 = i2.getFieldUnchecked(c); + if ("collectorState".equals(components1[c].name) && (o1 == null || o2 == null)) + continue; + if (!ObjectUtils.objectEquals(o1, o2)) + return false; + } + return true; + } + + static { + txtFilter = new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.toLowerCase().endsWith(".txt"); + } + }; + } + + private static Datatype stripUnitAnnotations(Datatype datatype) { + if (datatype instanceof NumberType) { + NumberType nt = (NumberType) datatype; + if (nt.getUnit() != null) { + Binding dtb = Bindings.getBindingUnchecked(Datatype.class); + datatype = nt = (NumberType) Bindings.cloneUnchecked(datatype, dtb, dtb); + nt.setUnit(null); + } + } else if (datatype instanceof ArrayType) { + ArrayType at = (ArrayType) datatype; + Datatype ct = at.componentType(); + Datatype component = stripUnitAnnotations(ct); + if (component != ct) { + Binding dtb = Bindings.getBindingUnchecked(Datatype.class); + datatype = at = (ArrayType) Bindings.cloneUnchecked(datatype, dtb, dtb); + at.setComponentType(component); + } + } else if (datatype instanceof RecordType) { + RecordType rt = (RecordType) datatype; + int componentCount = rt.getComponentCount(); + Component[] newComponents = new Component[componentCount]; + for (int i = 0; i < componentCount; ++i) { + Component c = rt.getComponent(i); + Datatype ct = c.type; + Datatype sct = stripUnitAnnotations(ct); + newComponents[i] = new Component(c.name, sct); + } + return new RecordType(rt.isReferable(), newComponents); + } + return datatype; + } + +}