Package org.apache.isis.runtimes.dflt.objectstores.nosql

Source Code of org.apache.isis.runtimes.dflt.objectstores.nosql.WriteObjectCommand

/*
*  Licensed to the Apache Software Foundation (ASF) under one
*  or more contributor license agreements.  See the NOTICE file
*  distributed with this work for additional information
*  regarding copyright ownership.  The ASF licenses this file
*  to you 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 org.apache.isis.runtimes.dflt.objectstores.nosql;

import java.util.ArrayList;
import java.util.List;

import org.apache.isis.core.commons.lang.ToString;
import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.oid.AggregatedOid;
import org.apache.isis.core.metamodel.adapter.version.Version;
import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
import org.apache.isis.core.metamodel.spec.DomainModelException;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.runtimes.dflt.runtime.persistence.objectstore.transaction.PersistenceCommand;
import org.apache.isis.runtimes.dflt.runtime.persistence.objectstore.transaction.PersistenceCommandContext;
import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;

class WriteObjectCommand implements PersistenceCommand {
    private final KeyCreator keyCreator;
    private final ObjectAdapter object;
    private final VersionCreator versionCreator;
    private final DataEncryption dataEncrypter;
    private final boolean isUpdate;

    WriteObjectCommand(
            final boolean isUpdate,
            final KeyCreator keyCreator,
            final VersionCreator versionCreator,
            final DataEncryption dataEncrypter,
            final ObjectAdapter object) {
        this.isUpdate = isUpdate;
        this.keyCreator = keyCreator;
        this.versionCreator = versionCreator;
        this.dataEncrypter = dataEncrypter;
        this.object = object;
    }

    @Override
    public void execute(final PersistenceCommandContext context) {
        final String specName = object.getSpecification().getFullIdentifier();
        final StateWriter writer = ((NoSqlCommandContext) context).createStateWriter(specName);
        final String key = keyCreator.key(object.getOid());
        writer.writeId(key);
        writeFields(writer, specName, object);
        final String user = IsisContext.getAuthenticationSession().getUserName();

        final Version currentVersion = object.getVersion();
        final Version newVersion =
            isUpdate ? versionCreator.nextVersion(currentVersion) : versionCreator.newVersion(user);
        object.setOptimisticLock(newVersion);
        if (newVersion != null) {
            final String version = currentVersion == null ? null : versionCreator.versionString(currentVersion);
            writer.writeVersion(version, versionCreator.versionString(newVersion));
            writer.writeUser(newVersion.getUser());
            writer.writeTime(versionCreator.timeString(newVersion));
            writer.writeEncryptionType(dataEncrypter.getType());
        }

        if (isUpdate) {
            ((NoSqlCommandContext) context).update(writer);
        } else {
            ((NoSqlCommandContext) context).insert(writer);
        }

    }

    private void writeFields(final StateWriter writer, final String specName, final ObjectAdapter object) {
        final List<ObjectAssociation> associations = object.getSpecification().getAssociations();
        writer.writeType(specName);
        for (final ObjectAssociation association : associations) {
            if (association.isNotPersisted()) {
                continue;
            }
            final ObjectAdapter field = association.get(object);
            if (association.isOneToManyAssociation()) {
                writeCollection(writer, association, field, keyCreator);
            } else if (association.getSpecification().isValue()) {
                writeValue(writer, association, field);
            } else if (association.getSpecification().isAggregated()) {
                writeAggregatedObject(writer, association, field, keyCreator);
            } else {
                writeReference(writer, association, field, keyCreator);
            }
        }
    }

    private void writeAggregatedObject(final StateWriter writer, final ObjectAssociation association,
        final ObjectAdapter field, final KeyCreator keyCreator) {
        if (field == null) {
            writer.writeField(association.getId(), null);
        } else if (field.getOid() instanceof AggregatedOid) {
            final String specName = field.getSpecification().getFullIdentifier();
            final StateWriter aggregateWriter = writer.addAggregate(association.getId());
            aggregateWriter.writeId(((AggregatedOid) field.getOid()).getId());
            writeFields(aggregateWriter, specName, field);
        } else {
            throw new NoSqlStoreException("Object type is inconsistent with it OID - it should have an AggregatedOid: "
                + field);
        }
    }

    private void writeReference(final StateWriter writer, final ObjectAssociation association,
        final ObjectAdapter reference, final KeyCreator keyCreator) {
        if (reference == null) {
            writer.writeField(association.getId(), null);
        } else {
            final String key = keyCreator.reference(reference);
            writer.writeField(association.getId(), key);
        }
    }

    private void writeValue(final StateWriter writer, final ObjectAssociation association, final ObjectAdapter value) {
        String data;
        if (value == null) {
            data = null;
        } else {
            final EncodableFacet encodeableFacet = value.getSpecification().getFacet(EncodableFacet.class);
            data = encodeableFacet.toEncodedString(value);
            data  = dataEncrypter.encrypt(data);
        }
        writer.writeField(association.getId(), data);
    }

    private void writeCollection(final StateWriter writer, final ObjectAssociation association,
        final ObjectAdapter collection, final KeyCreator keyCreator) {
        final CollectionFacet collectionFacet = collection.getSpecification().getFacet(CollectionFacet.class);
        if (association.getSpecification().isAggregated()) {
            final List<StateWriter> elements = new ArrayList<StateWriter>();
            for (final ObjectAdapter element : collectionFacet.iterable(collection)) {
                final StateWriter elementWriter = writer.createElementWriter();
                elementWriter.writeId(((AggregatedOid) element.getOid()).getId());
                writeFields(elementWriter, element.getSpecification().getFullIdentifier(), element);
                elements.add(elementWriter);
            }
            writer.writeCollection(association.getId(), elements);
        } else {
            String refs = "";
            for (final ObjectAdapter element : collectionFacet.iterable(collection)) {
                if (element.isAggregated()) {
                    throw new DomainModelException(
                        "Can't store an aggregated object within a collection that is not exoected aggregates: "
                            + element + " (" + collection + ")");
                }
                refs += keyCreator.reference(element) + "|";
            }
            if (refs.length() > 0) {
                writer.writeField(association.getId(), refs);
            }
        }
    }

    @Override
    public ObjectAdapter onObject() {
        return object;
    }

    @Override
    public String toString() {
        final ToString toString = new ToString(this);
        toString.append("spec", object.getSpecification().getFullIdentifier());
        toString.append("oid", object.getOid());
        return toString.toString();
    }
}
TOP

Related Classes of org.apache.isis.runtimes.dflt.objectstores.nosql.WriteObjectCommand

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.