/******************************************************************************* * Copyright (c) 2007, 2010 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.db.layer0.adapter.impl; import java.lang.reflect.Array; import java.util.List; import org.simantics.databoard.Bindings; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.RecordBinding; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.parser.repository.DataTypeSyntaxError; import org.simantics.databoard.parser.repository.DataValueRepository; import org.simantics.databoard.type.ArrayType; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.type.RecordType; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ValidationException; import org.simantics.db.layer0.adapter.StringIndexModifier; import org.simantics.db.layer0.adapter.TObjectIntPair; import org.simantics.db.layer0.util.PrimitiveValueParser; import org.simantics.db.layer0.util.PrimitiveValueParser.BooleanValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.ByteValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.DoubleValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.FloatValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.IValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.IntegerValidator; import org.simantics.db.layer0.util.PrimitiveValueParser.LongValidator; import org.simantics.db.service.VirtualGraphSupport; import org.simantics.layer0.Layer0; /** * @author Tuukka Lehtonen */ public final class StringIndexModifierImpl implements StringIndexModifier { final Resource resource; IValidator validator; public StringIndexModifierImpl(ReadGraph g, Resource resource) throws DatabaseException { this.resource = resource; this.validator = null; // Resolve validator if any Layer0 l0 = Layer0.getInstance(g); if (g.isInstanceOf(resource, l0.DoubleArray)) { validator = new DoubleValidator(); } else if (g.isInstanceOf(resource, l0.ByteArray)) { validator = new ByteValidator(); } else if (g.isInstanceOf(resource, l0.BooleanArray)) { validator = new BooleanValidator(); } else if (g.isInstanceOf(resource, l0.IntegerArray)) { validator = new IntegerValidator(); } else if (g.isInstanceOf(resource, l0.LongArray)) { validator = new LongValidator(); } else if (g.isInstanceOf(resource, l0.FloatArray)) { validator = new FloatValidator(); } } @Override public String getValue() { throw new UnsupportedOperationException(); } @Override public String isValid(TObjectIntPair value) { return validator == null ? null : validator.isValid(value.first); } @Override public void modify(WriteGraph graph, final TObjectIntPair pair) throws DatabaseException { VirtualGraphSupport vgs = graph.getService(VirtualGraphSupport.class); VirtualGraph vg = vgs.getGraph(graph, resource); if (vg != null) { graph.syncRequest(new WriteRequest(vg) { @Override public void perform(WriteGraph graph) throws DatabaseException { modify0(graph, pair); } }); } else { modify0(graph, pair); } } public void modify0(WriteGraph graph, TObjectIntPair pair) throws DatabaseException { Layer0 l0 = Layer0.getInstance(graph); String value = pair.first; int index = pair.second; try { if (graph.isInstanceOf(resource, l0.StringArray)) { String[] old = graph.getValue(resource); old[index] = value; graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.DoubleArray)) { double[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseDouble(value); graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.ByteArray)) { byte[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseByte(value); graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.BooleanArray)) { boolean[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseBoolean(value); graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.IntegerArray)) { int[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseInt(value); graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.LongArray)) { long[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseLong(value); graph.claimValue(resource, old); } else if (graph.isInstanceOf(resource, l0.FloatArray)) { float[] old = graph.getValue(resource); old[index] = PrimitiveValueParser.parseFloat(value); graph.claimValue(resource, old); } else if(graph.isInstanceOf(resource, l0.OrderedSet)) { List list = OrderedSetUtils.toList(graph, resource); Resource el = graph.newResource(); graph.claimValue(el, value); graph.claim(el, l0.InstanceOf, null, l0.String); // FIXME FIXME FIXME OrderedSetUtils.replace(graph, resource, list.get(index), el); } else { Datatype dt = graph.getPossibleRelatedValue(resource, l0.HasDataType, Bindings.getBindingUnchecked(Datatype.class)); if (dt instanceof RecordType) { RecordType rt = (RecordType) dt; RecordBinding rb = Bindings.getBinding(rt); Binding indexBinding = rb.getComponentBinding(index); Object parsedValue = indexBinding.parseValue(value, new DataValueRepository()); Object v = graph.getValue(resource, rb); rb.setComponent(v, index, parsedValue); graph.claimValue(resource, v, rb); } else if (dt instanceof ArrayType) { ArrayType at = (ArrayType) dt; Binding binding = Bindings.getBinding(at); Binding indexBinding = Bindings.getBinding(at.componentType()); Object parsedValue = indexBinding.parseValue(value, new DataValueRepository()); Object v = graph.getValue(resource, binding); if (v.getClass().isArray()) { Array.set(v, index, parsedValue); graph.claimValue(resource, v, binding); } } else { throw new ValidationException("Could not modify unrecognized resource '" + NameUtils.getSafeName(graph, resource) + "' with value " + value); } } } catch(IllegalArgumentException e) { // value could not be modified } catch (DataTypeSyntaxError e) { throw new ValidationException("Could not modify unrecognized resource '" + NameUtils.getSafeName(graph, resource) + "' with value " + value, e); } catch (BindingException e) { throw new ValidationException("Could not modify unrecognized resource '" + NameUtils.getSafeName(graph, resource) + "' with value " + value, e); } } }