Package ch.agent.crnickl.impl

Source Code of ch.agent.crnickl.impl.UpdatableSchemaImpl

/*
*   Copyright 2012 Hauser Olsson GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Package: ch.agent.crnickl.impl
* Type: UpdatableSchemaImpl
* Version: 1.1.0
*/
package ch.agent.crnickl.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import ch.agent.crnickl.T2DBException;
import ch.agent.crnickl.T2DBMsg;
import ch.agent.crnickl.T2DBMsg.D;
import ch.agent.crnickl.api.AttributeDefinition;
import ch.agent.crnickl.api.DBObjectType;
import ch.agent.crnickl.api.Property;
import ch.agent.crnickl.api.Schema;
import ch.agent.crnickl.api.SeriesDefinition;
import ch.agent.crnickl.api.Surrogate;
import ch.agent.crnickl.api.UpdatableSchema;
import ch.agent.crnickl.api.ValueType;
import ch.agent.t2.time.TimeDomain;

/**
* Default implementation of {@link UpdatableSchema}.
*
* @author Jean-Paul Vetterli
* @version 1.1.0
*/
public class UpdatableSchemaImpl extends SchemaImpl implements UpdatableSchema {

  private boolean delete;
  private UpdatableSchema base;
  private String editedName;
  private UpdatableSchema editedBase;
  private boolean editedBaseSet;
 
  /**
   * Construct an {@link UpdatableSchema}.
   *
   * @param name a string
   * @param base a base schema
   * @param attributeDefs a collection of attribute definitions
   * @param seriesDefinitions a collection of series definitions
   * @param surrogate a surrogate
   */
  public UpdatableSchemaImpl(String name, UpdatableSchema base,
      Collection<AttributeDefinition<?>> attributeDefs,
      Collection<SeriesDefinition> seriesDefinitions, Surrogate surrogate) {
    super(true, name, attributeDefs, seriesDefinitions, surrogate, null);
    this.base = base;
  }

  @Override
  public void applyUpdates() throws T2DBException {
    if (delete) {
      // cache already cleared
      getDatabase().deleteSchema(this);
      delete = false;
    } else {
      if (getSurrogate().inConstruction()) {
        getDatabase().create(this);
        if (editedBaseSet)
          base = editedBase;
        editedBaseSet = false;
        editedName = null;
        editedBase = null;
      } else
        getDatabase().getCache().clear(this);
      getDatabase().update(this);
      update();
    }
  }
 
  @Override
  protected void update() throws T2DBException {
    super.update();
    if (editedBaseSet)
      base = editedBase;
    editedBaseSet = false;
    editedBase = null;
    editedName = null;
    getAttributeDefinitionsObject().consolidate();
    getSeriesDefinitionsObject().consolidate();
  }

  @Override
  public UpdatableSchema edit() {
    return this;
  }

  @Override
  public void destroy() throws T2DBException {
    delete = true;
  }
 
  @Override
  public String getName() {
    if (editedName != null)
      return editedName;
    else
      return super.getName();
  }
 
  @Override
  public void setName(String name) throws T2DBException {
    if (name != null && name.length() == 0)
      name = null;
    this.editedName = name;
  }

  @Override
  public UpdatableSchema getBase() {
    if (editedBase != null)
      return editedBase;
    else
      return base;
  }

  /**
   * Return the base schema before it was modified with
   * {@link #setBase(UpdatableSchema)}.
   * Return the same result as {@link #getBase} if the base schema was not modified.
   *
   * @return a schema
   */
  public UpdatableSchema getPreviousBase() {
    return base;
  }
 
  @Override
  public void setBase(UpdatableSchema base) throws T2DBException {
    this.editedBase = base;
  }
 
  @Override
  public SeriesDefinition addSeries(int seriesNr) throws T2DBException {
    return addSeries(seriesNr, false);
  }
 
  private SeriesDefinition addSeries(int seriesNr, boolean merging) throws T2DBException {
    SeriesDefinition ss = new SeriesDefinitionImpl(seriesNr, null, null);
    boolean added = getSeriesDefinitionsObject().addComponent(ss);
    if (!(added || merging))
      throw T2DBMsg.exception(D.D30124, seriesNr, this);
    return ss;
  }

  @Override
  public void deleteSeries(int seriesNr) throws T2DBException {
    getSeriesDefinitionsObject().deleteComponent(seriesNr);
  }

  @Override
  public void eraseSeries(int seriesNr) throws T2DBException {
    startEditingSeriesSchema(seriesNr).setErasing(true);
  }

  @Override
  public void setSeriesDescription(int seriesNr, String description) throws T2DBException {
    editSeriesAttributeDefinition(seriesNr, DatabaseBackend.MAGIC_NAME_NR, true);
    startEditingSeriesSchema(seriesNr).setDescription(description)
  }

  @SuppressWarnings("unchecked")
  @Override
  public void setSeriesName(int seriesNr, String name) throws T2DBException {
    AttributeDefinitionImpl<String> def = (AttributeDefinitionImpl<String>)
      editSeriesAttributeDefinition(seriesNr, DatabaseBackend.MAGIC_NAME_NR, false);
    if (def == null) {
      Property<String> property = (Property<String>) getBuiltInProperty(DatabaseBackend.MAGIC_NAME_NR);
      def = (AttributeDefinitionImpl<String>) addAttribute(seriesNr, DatabaseBackend.MAGIC_NAME_NR);
      def.setProperty(property);
    }
    def.setValue(name);
  }

  @SuppressWarnings("unchecked")
  @Override
  public void setSeriesType(int seriesNr, ValueType<?> type) throws T2DBException {
    AttributeDefinitionImpl<ValueType<?>> def = (AttributeDefinitionImpl<ValueType<?>>)
      editSeriesAttributeDefinition(seriesNr, DatabaseBackend.MAGIC_TYPE_NR, false);
    if (def == null) {
      Property<ValueType<?>> property = (Property<ValueType<?>>) getBuiltInProperty(DatabaseBackend.MAGIC_TYPE_NR);
      def = (AttributeDefinitionImpl<ValueType<?>>) addAttribute(seriesNr, DatabaseBackend.MAGIC_TYPE_NR);
      def.setProperty(property);
    }
    def.setValue(type);
  }

  @Override
  public void setSeriesType(int seriesNr, String type) throws T2DBException {
    DatabaseBackend db = ((SurrogateImpl)getSurrogate()).getDatabase();
    Surrogate surrogate = new SurrogateImpl(db, DBObjectType.VALUE_TYPE, DatabaseBackend.MAGIC_TYPE_NR);
    @SuppressWarnings({ "rawtypes" })
    ValueType<ValueType> vt = db.getValueType(surrogate);
    setSeriesType(seriesNr, vt.scan(type));
  }
 
  @SuppressWarnings("unchecked")
  @Override
  public void setSeriesTimeDomain(int seriesNr, TimeDomain timeDomain) throws T2DBException {
    AttributeDefinitionImpl<TimeDomain> def = (AttributeDefinitionImpl<TimeDomain>)
      editSeriesAttributeDefinition(seriesNr, DatabaseBackend.MAGIC_TIMEDOMAIN_NR, false);
    if (def == null) {
      Property<TimeDomain> property = (Property<TimeDomain>) getBuiltInProperty(DatabaseBackend.MAGIC_TIMEDOMAIN_NR);
      def = (AttributeDefinitionImpl<TimeDomain>) addAttribute(seriesNr, DatabaseBackend.MAGIC_TIMEDOMAIN_NR);
      def.setProperty(property);
    }
    def.setValue(timeDomain);
  }
 
  @SuppressWarnings("unchecked")
  @Override
  public void setSeriesSparsity(int seriesNr, boolean sparsethrows T2DBException {
    AttributeDefinitionImpl<Boolean> def = (AttributeDefinitionImpl<Boolean>)
        editSeriesAttributeDefinition(seriesNr, DatabaseBackend.MAGIC_SPARSITY_NR, false);
      if (def == null) {
        Property<Boolean> property = (Property<Boolean>) getBuiltInProperty(DatabaseBackend.MAGIC_SPARSITY_NR);
        def = (AttributeDefinitionImpl<Boolean>) addAttribute(seriesNr, DatabaseBackend.MAGIC_SPARSITY_NR);
        def.setProperty(property);
      }
      def.setValue(sparse);
  }

  /**
   * Return the collection of edited series definitions.
   *
   * @return the collection of edited series definitions
   */
  public Collection<SeriesDefinition> getEditedSeriesDefinitions() {
    return getSeriesDefinitionsObject().getEditedComponents();
  }

  /**
   * Return the collection of deleted series definitions.
   *
   * @return the collection of deleted series definitions
   */
  public Set<Integer> getDeletedSeriesDefinitions() {
    return getSeriesDefinitionsObject().getDeletedComponents();
  }

  @Override
  public AttributeDefinition<?> addAttribute(int attrNr) throws T2DBException {
    return addAttribute(attrNr, false);
  }
 
  private AttributeDefinition<?> addAttribute(int attrNr, boolean merging) throws T2DBException {
    @SuppressWarnings({ "unchecked", "rawtypes" })
    AttributeDefinition<?> def = new AttributeDefinitionImpl(attrNr, null, null);
    boolean added = getAttributeDefinitionsObject().addComponent(def);
    if (!(added || merging))
      throw T2DBMsg.exception(D.D30127, attrNr, this);
    return def;
  }

  @Override
  public void deleteAttribute(int attrNr) throws T2DBException {
    getAttributeDefinitionsObject().deleteComponent(attrNr);
  }

  @Override
  public void eraseAttribute(int attrNr) throws T2DBException {
    editAttributeDefinition(attrNr).setErasing(true);
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  @Override
  public <T>void setAttributeProperty(int attrNr, Property<T> property) throws T2DBException {
    editAttributeDefinition(attrNr).setProperty((Property)property);
  }

  @Override
  public <T>void setAttributeDefault(int attrNr, T defaultValue) throws T2DBException {
    editAttributeDefinition(attrNr).setValue(defaultValue);
  }
 
  @Override
  public AttributeDefinition<?> addAttribute(int seriesNr, int attrNr) throws T2DBException {
    return addAttribute(seriesNr, attrNr, false);
  }
 
  private AttributeDefinition<?> addAttribute(int seriesNr, int attrNr, boolean merging) throws T2DBException {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    AttributeDefinition<?> def = new AttributeDefinitionImpl(attrNr, null, null);
    boolean added = startEditingSeriesSchema(seriesNr).getAttributeDefinitionsObject().addComponent(def);
    if (!(added || merging))
      throw T2DBMsg.exception(D.D30118, attrNr, seriesNr, this);
    return def;
  }

  @Override
  public void deleteAttribute(int seriesNr, int attrNr) throws T2DBException {
    startEditingSeriesSchema(seriesNr).getAttributeDefinitionsObject().deleteComponent(attrNr);
  }

  @Override
  public void eraseAttribute(int seriesNr, int attrNr) throws T2DBException {
    editSeriesAttributeDefinition(seriesNr, attrNr, true).setErasing(true);
  }
 
  @SuppressWarnings({ "unchecked", "rawtypes" })
  @Override
  public void setAttributeProperty(int seriesNr, int attrNr,  Property<?> property) throws T2DBException {
    editSeriesAttributeDefinition(seriesNr, attrNr, true).setProperty((Property) property);
  }

  @Override
  public void setAttributeDefault(int seriesNr, int attrNr, Object defaultValue) throws T2DBException {
    editSeriesAttributeDefinition(seriesNr, attrNr, true).setValue(defaultValue);
  }

  /**
   * Return the collection of edited series attribute definitions.
   *
   * @param seriesNr a series number
   * @return the collection of edited series attribute definitions
   * @throws T2DBException
   */
  public Collection<AttributeDefinition<?>> getEditedAttributeDefinitions(int seriesNr) throws T2DBException {
    // note: only edited schemas have edited attribute definitions
    SeriesDefinitionImpl schema = (SeriesDefinitionImpl) findEditedSeriesSchema(seriesNr);
    return schema == null new ArrayList<AttributeDefinition<?>>() :
      schema.getAttributeDefinitionsObject().getEditedComponents();
  }

  /**
   * Return the collection of deleted series attribute definitions.
   *
   * @param seriesNr a series number
   * @return the collection of deleted series attribute definitions
   * @throws T2DBException
   */
  public Set<Integer> getDeletedAttributeDefinitions(int seriesNr) throws T2DBException {
    // note: only edited schemas have deleted attribute definitions
    SeriesDefinitionImpl schema = (SeriesDefinitionImpl) findEditedSeriesSchema(seriesNr);
    return schema == null ? new HashSet<Integer>() :
      schema.getAttributeDefinitionsObject().getDeletedComponents();
  }

  /**
   * Return the collection of edited attribute definitions.
   *
   * @return the collection of edited attribute definitions
   * @throws T2DBException
   */
  public Collection<AttributeDefinition<?>> getEditedAttributeDefinitions() {
    return getAttributeDefinitionsObject().getEditedComponents();
  }

  /**
   * Return the collection of deleted attribute definitions.
   *
   * @return the collection of deleted attribute definitions
   * @throws T2DBException
   */
  public Set<Integer> getDeletedAttributeDefinitions() {
    return getAttributeDefinitionsObject().getDeletedComponents();
  }

  /**
   * Find an edited series definition.
   *
   * @param seriesNr a series number
   * @return an edited series definition
   * @throws T2DBException
   */
  protected SeriesDefinition findEditedSeriesSchema(int seriesNr) throws T2DBException {
    SeriesDefinition schema = null;
    for (SeriesDefinition ss : this.getEditedSeriesDefinitions()) {
      if (ss.getNumber() == seriesNr) {
        schema = ss;
      }
    }
    return schema;
  }
 
  /**
   * Start editing a series definition.
   *
   * @param seriesNr a series number
   * @return a series definition
   * @throws T2DBException
   */
  protected SeriesDefinitionImpl startEditingSeriesSchema(int seriesNr) throws T2DBException {
    SeriesDefinitionImpl sch = (SeriesDefinitionImpl) getSeriesDefinitionsObject().edit(seriesNr);
    if (sch == null)
      throw T2DBMsg.exception(D.D30125, seriesNr, getName());
    return sch;
  }
 
  /**
   * Start editing an attribute definition.
   *
   * @param attrNr an attribute number
   * @return an attribute definition
   * @throws T2DBException
   */
  protected AttributeDefinitionImpl<?> editAttributeDefinition(int attrNr) throws T2DBException {
    AttributeDefinitionImpl<?> def = (AttributeDefinitionImpl<?>) getAttributeDefinitionsObject().edit(attrNr);
    if (def == null)
      throw T2DBMsg.exception(D.D30123, attrNr, getName());
    return def;
  }

  /**
   * Start editing a series attribute definition.
   * @param seriesNr a series number
   * @param attrNr an attribute number
   * @param mustExist if true throw an exception instead of returning null
   * @return an attribute definition or null if there is no such attribute definition
   * @throws T2DBException
   */
  protected AttributeDefinitionImpl<?> editSeriesAttributeDefinition(int seriesNr, int attrNr, boolean mustExist) throws T2DBException {
    AttributeDefinitionImpl<?> def = (AttributeDefinitionImpl<?>) startEditingSeriesSchema(seriesNr).getAttributeDefinitionsObject().edit(attrNr);
    if (def == null && mustExist)
      throw T2DBMsg.exception(D.D30126, attrNr, seriesNr, getName());
    return def;
  }
 
//  private void dump(String ASUD, Integer number, PrintStream out) throws T2DBException {
//    out.println(String.format("  %s #%d", ASUD, number));
//  }
// 
//  private void dump(String ASUD, AttributeDefinition<?> def, PrintStream out) throws T2DBException {
//    if (def.isErasing())
//      out.println(String.format("  %s #%d *ERASING*", ASUD, def.getNumber()));
//    else
//      out.println(String.format("  %s #%d %s=%s", ASUD, def.getNumber(), def.getName(), def.getValue()));
//  }
// 
//  private void dump(String ASUD, SeriesDefinitionImpl ss, PrintStream out) throws T2DBException {
//    if (ss.isErasing())
//      out.println(String.format("  %s #%d *ERASING*", ASUD, ss.getNumber()));
//    else {
//      out.println(String.format("  %s #%d", ASUD, ss.getNumber()));
//      if (ss.getName() != null)
//        out.println(String.format("    Name=%s", ss.getName()));
//      if (ss.getDescription() != null)
//        out.println(String.format("    Description=%s", ss.getDescription()));
//      if (ss.getValueType() != null)
//        out.println(String.format("    Type=%s", ss.getValueType()));
//      if (ss.getTimeDomain() != null)
//        out.println(String.format("    TimeDomain=%s", ss.getTimeDomain().getLabel()));
//     
//      for (AttributeDefinition<?> def : ss.getAttributeDefinitions()) {
//        dump("  A ", def, out);
//      }
//      for (AttributeDefinition<?> def : this.getEditedAttributeDefinitions(ss.getNumber())) {
//        dump("  AE", def, out);
//      }
//      for (Integer def : this.getDeletedAttributeDefinitions(ss.getNumber())) {
//        dump("  AD", def, out);
//      }
//    }
//  }
// 
//  @Override
//  public void dump(PrintStream out) throws T2DBException {
//    out.println(String.format("%s %s (ready: %b)", this.getName(),
//        getSurrogate().inConstruction() ? "*IN CONSTRUCTION*" : getSurrogate().toString(),
//        isComplete()));
//    out.println("  Extends: " + (this.getBase() == null ? " - " : this.getBase()));
//    for (AttributeDefinition<?> def : this.getAttributeDefinitions()) {
//      dump("A ", def, out);
//    }
//    for (AttributeDefinition<?> def : this.getEditedAttributeDefinitions()) {
//      dump("AE", def, out);
//    }
//    for (Integer def : this.getDeletedAttributeDefinitions()) {
//      dump("AD", def, out);
//    }
//
//    for (SeriesDefinition ss : this.getSeriesDefinitions()) {
//      dump("S ", (SeriesDefinitionImpl) ss, out);
//    }
//    for (SeriesDefinition ss : this.getEditedSeriesDefinitions()) {
//      dump("SE", (SeriesDefinitionImpl) ss, out);
//    }
//    for (Integer number : this.getDeletedSeriesDefinitions()) {
//      dump("SD", number, out);
//    }
//
//  }

  private Property<?> getBuiltInProperty(int magicNumber) throws T2DBException {
    SurrogateImpl thisKey = (SurrogateImpl) getSurrogate();
    Surrogate propKey = new SurrogateImpl(thisKey.getDatabase(), DBObjectType.PROPERTY, magicNumber);
    return thisKey.getDatabase().getProperty(propKey);
  }
 
  /**
   * Merge a schema into this schema.
   *
   * @param schema a schema
   *
   * @throws T2DBException
   */
  public void merge(UpdatableSchema schema) throws T2DBException {
    for (AttributeDefinition<?> def : schema.getAttributeDefinitions()) {
      int dn = def.getNumber();
      if (def.isErasing())
        deleteAttribute(dn);
      else {
        addAttribute(dn, true);
        if (def.getProperty() != null)
          setAttributeProperty(dn, def.getProperty());
        if (def.getValue() != null)
          setAttributeDefault(dn, def.getValue());
      }
    }
   
    for (SeriesDefinition ss : schema.getSeriesDefinitions()) {
      int sn = ss.getNumber();
      if (ss.isErasing())
        deleteSeries(sn);
      else {
        addSeries(sn, true);
        for (AttributeDefinition<?> def : ss.getAttributeDefinitions()) {
          int dn = def.getNumber();
          if (def.isErasing())
            deleteAttribute(sn, dn);
          else {
            addAttribute(sn, dn, true);
            if (def.getProperty() != null)
              setAttributeProperty(sn, dn, def.getProperty());
            if (def.getValue() != null)
              setAttributeDefault(sn, dn, def.getValue());
          }
        }
        if (ss.getDescription() != null)
          setSeriesDescription(sn, ss.getDescription());
      }
    }
  }
 
  /**
   * Apply all changes and return the schema as a standard read-only schema.
   *
   * @return a schema
   */
  public Schema consolidate(String name, Surrogate surrogate, List<Surrogate> dependencyList) throws T2DBException {
    try {
      getAttributeDefinitionsObject().consolidate();
      getSeriesDefinitionsObject().consolidate();
    } catch (T2DBException e) {
      throw T2DBMsg.exception(e, D.D30129, name);
    }
    return new SchemaImpl(name, getAttributeDefinitions(), getSeriesDefinitions(), surrogate, dependencyList);
  }
 
 
}
TOP

Related Classes of ch.agent.crnickl.impl.UpdatableSchemaImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.