Package com.orientechnologies.orient.core.record

Source Code of com.orientechnologies.orient.core.record.ORecordAbstract

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* 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 com.orientechnologies.orient.core.record;

import java.util.Arrays;

import com.orientechnologies.orient.core.db.record.ODatabaseRecord;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordElement;
import com.orientechnologies.orient.core.exception.ODatabaseException;
import com.orientechnologies.orient.core.exception.ORecordNotFoundException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.serialization.serializer.record.ORecordSerializer;
import com.orientechnologies.orient.core.serialization.serializer.record.string.ORecordSerializerJSON;

@SuppressWarnings({ "unchecked", "serial" })
public abstract class ORecordAbstract<T> implements ORecord<T>, ORecordInternal<T> {
  protected ODatabaseRecord        _database;
  protected ORecordId              _recordId;
  protected int                    _version;
  protected byte[]                _source;
  protected int                    _size;
  protected ORecordSerializer      _recordFormat;
  protected boolean                _pinned    = true;
  protected boolean                _dirty    = true;
  protected ORecordElement.STATUS  _status    = ORecordElement.STATUS.LOADED;
  protected ORecordListener        _listener  = null;

  public ORecordAbstract() {
  }

  public ORecordAbstract(final ODatabaseRecord iDatabase) {
    _database = iDatabase;
  }

  public ORecordAbstract(final ODatabaseRecord iDatabase, final byte[] iSource) {
    this(iDatabase);
    _source = iSource;
    _size = iSource.length;
    unsetDirty();
  }

  public ORecordAbstract<?> fill(final ODatabaseRecord iDatabase, final ORecordId iRid, final int iVersion, final byte[] iBuffer,
      boolean iDirty) {
    _database = iDatabase;
    _recordId.clusterId = iRid.clusterId;
    _recordId.clusterPosition = iRid.clusterPosition;
    _version = iVersion;
    _status = ORecordElement.STATUS.LOADED;
    _source = iBuffer;
    _size = iBuffer != null ? iBuffer.length : 0;
    if (_source != null && _source.length > 0)
      _dirty = iDirty;

    return this;
  }

  public ORID getIdentity() {
    return _recordId;
  }

  public ORecord<?> getRecord() {
    return this;
  }

  public ORecordAbstract<?> setIdentity(final int iClusterId, final long iClusterPosition) {
    if (_recordId == null || _recordId == ORecordId.EMPTY_RECORD_ID)
      _recordId = new ORecordId(iClusterId, iClusterPosition);
    else {
      _recordId.clusterId = iClusterId;
      _recordId.clusterPosition = iClusterPosition;
    }
    return this;
  }

  public ORecordAbstract<?> setIdentity(final ORecordId iIdentity) {
    _recordId = iIdentity;
    return this;
  }

  public boolean detach() {
    _database = null;
    return true;
  }

  public ORecordAbstract<T> clear() {
    setDirty();
    invokeListenerEvent(ORecordListener.EVENT.CLEAR);
    return this;
  }

  public ORecordAbstract<T> reset() {
    _status = ORecordElement.STATUS.LOADED;
    _version = 0;

    setDirty();
    if (_recordId != null)
      _recordId.reset();

    invokeListenerEvent(ORecordListener.EVENT.RESET);

    return this;
  }

  public byte[] toStream() {
    if (_source == null)
      _source = _recordFormat.toStream(_database, this, false);

    invokeListenerEvent(ORecordListener.EVENT.MARSHALL);

    return _source;
  }

  public ORecordAbstract<T> fromStream(final byte[] iRecordBuffer) {
    _dirty = false;
    _source = iRecordBuffer;
    _size = iRecordBuffer != null ? iRecordBuffer.length : 0;
    _status = ORecordElement.STATUS.LOADED;

    invokeListenerEvent(ORecordListener.EVENT.UNMARSHALL);

    return this;
  }

  public void unsetDirty() {
    if (_dirty)
      _dirty = false;
  }

  public ORecordAbstract<T> setDirty() {
    if (!_dirty && _status != STATUS.UNMARSHALLING)
      _dirty = true;
    _source = null;
    return this;
  }

  public void onBeforeIdentityChanged(final ORID iRID) {
  }

  public void onAfterIdentityChanged(final ORecord<?> iRecord) {
  }

  public boolean isDirty() {
    return _dirty;
  }

  public boolean isPinned() {
    return _pinned;
  }

  public ORecordAbstract<T> pin() {
    if (!_pinned)
      _pinned = true;
    return this;
  }

  public ORecordAbstract<T> unpin() {
    if (_pinned)
      _pinned = false;
    return this;
  }

  public ODatabaseRecord getDatabase() {
    return _database;
  }

  public boolean setDatabase(final ODatabaseRecord iDatabase) {
    if (_database != iDatabase) {
      this._database = iDatabase;
      return true;
    }
    return false;
  }

  public <RET extends ORecord<T>> RET fromJSON(final String iSource) {
    ORecordSerializerJSON.INSTANCE.fromString(_database, iSource, this);
    return (RET) this;
  }

  public String toJSON() {
    return toJSON("rid,version,class,type,attribSameRow");
  }

  public String toJSON(final String iFormat) {
    return ORecordSerializerJSON.INSTANCE.toString(this, new StringBuilder(), iFormat).toString();
  }

  @Override
  public String toString() {
    return (_recordId.isValid() ? _recordId : "") + (_source != null ? Arrays.toString(_source) : "[]") + " v" + _version;
  }

  public int getVersion() {
    return _version;
  }

  public void setVersion(final int iVersion) {
    _version = iVersion;
  }

  public ORecordAbstract<T> unload() {
    _status = ORecordElement.STATUS.NOT_LOADED;
    _source = null;
    unsetDirty();
    invokeListenerEvent(ORecordListener.EVENT.UNLOAD);
    return this;
  }

  public ORecordInternal<T> load() {
    if (_database == null)
      throw new ODatabaseException("No database assigned to current record");

    if (!getIdentity().isValid())
      throw new ORecordNotFoundException("The record has no id, probably it's new or transient yet ");

    try {
      final ORecordInternal<?> result = _database.load(this);

      if (result == null)
        throw new ORecordNotFoundException("The record with id '" + getIdentity() + "' was not found");

      return (ORecordInternal<T>) result;
    } catch (Exception e) {
      throw new ORecordNotFoundException("The record with id '" + getIdentity() + "' was not found", e);
    }
  }

  public ORecordInternal<T> reload() {
    return reload(null);
  }

  public ORecordInternal<T> reload(final String iFetchPlan) {
    return reload(null, true);
  }

  public ORecordInternal<T> reload(final String iFetchPlan, final boolean iIgnoreCache) {
    if (_database == null)
      throw new ODatabaseException("No database assigned to current record");

    if (!getIdentity().isValid())
      throw new ORecordNotFoundException("The record has no id, probably it's new or transient yet ");

    try {
      _database.reload(this, iFetchPlan, iIgnoreCache);

      // GET CONTENT
      // fromStream(toStream());

      return this;
    } catch (Exception e) {
      throw new ORecordNotFoundException("The record with id '" + getIdentity() + "' was not found", e);
    }
  }

  public ORecordAbstract<T> save() {
    if (_database == null)
      throw new ODatabaseException("No database assigned to current record. Create it using the <DB>.newInstance()");

    _database.save(this);

    return this;
  }

  public ORecordAbstract<T> save(final String iClusterName) {
    if (_database == null)
      throw new ODatabaseException("No database assigned to current record. Create it using the <DB>.newInstance()");

    _database.save(this, iClusterName);

    return this;
  }

  public ORecordAbstract<T> delete() {
    if (_database == null)
      throw new ODatabaseException("No database assigned to current record");

    _database.delete(this);
    setDirty();
    return this;
  }

  public int getSize() {
    return _size;
  }

  protected void setup() {
    if (_recordId == null)
      _recordId = new ORecordId();
  }

  @Override
  public int hashCode() {
    return _recordId != null ? _recordId.hashCode() : 0;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;

    if (obj instanceof OIdentifiable)
      return _recordId.equals(((OIdentifiable) obj).getIdentity());

    return false;
  }

  public int compare(final OIdentifiable iFirst, final OIdentifiable iSecond) {
    if (iFirst == null || iSecond == null)
      return -1;
    return iFirst.compareTo(iSecond);
  }

  public int compareTo(final OIdentifiable iOther) {
    if (iOther == null)
      return 1;

    if (_recordId == null && iOther.getIdentity() == null)
      return 0;

    return _recordId.compareTo(iOther.getIdentity());
  }

  public ORecordElement.STATUS getInternalStatus() {
    return _status;
  }

  public void setInternalStatus(final ORecordElement.STATUS iStatus) {
    this._status = iStatus;
  }

  public ORecordAbstract<T> copyTo(final ORecordAbstract<T> cloned) {
    cloned._source = _source;
    cloned._size = _size;
    cloned._database = _database;
    cloned._recordId = _recordId.copy();
    cloned._version = _version;
    cloned._pinned = _pinned;
    cloned._status = _status;
    cloned._recordFormat = _recordFormat;
    cloned._listener = null;
    cloned._dirty = false;
    return cloned;
  }

  /**
   * Add a listener to the current document to catch all the supported events.
   *
   * @see ORecordListener
   *
   * @param iListener
   *          ODocumentListener implementation
   */
  public void setListener(final ORecordListener iListener) {
    _listener = iListener;
  }

  /**
   * Remove the current event listener.
   *
   * @see ORecordListener
   */
  public void removeListener() {
    _listener = null;
  }

  protected void invokeListenerEvent(final ORecordListener.EVENT iEvent) {
    if (_listener != null)
      _listener.onEvent(this, iEvent);
  }

  public <RET extends ORecord<T>> RET flatCopy() {
    return (RET) copy();
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.record.ORecordAbstract

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.