Package org.apache.isis.objectstore.nosql

Source Code of org.apache.isis.objectstore.nosql.ObjectReader

/*
*  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.objectstore.nosql;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.adapter.ResolveState;
import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
import org.apache.isis.core.metamodel.adapter.oid.AggregatedOid;
import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
import org.apache.isis.core.metamodel.adapter.oid.RootOid;
import org.apache.isis.core.metamodel.adapter.oid.TypedOid;
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.SpecificationLoaderSpi;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationContainer;
import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
import org.apache.isis.core.runtime.system.context.IsisContext;
import org.apache.isis.core.runtime.system.persistence.Persistor;
import org.apache.isis.objectstore.nosql.db.StateReader;
import org.apache.isis.objectstore.nosql.encryption.DataEncryption;
import org.apache.isis.objectstore.nosql.keys.KeyCreatorDefault;
import org.apache.isis.objectstore.nosql.versions.VersionCreator;

public class ObjectReader {

    private static final Logger LOG = LoggerFactory.getLogger(ObjectReader.class);
   
    private final KeyCreatorDefault keyCreator = new KeyCreatorDefault();

    public ObjectAdapter load(final StateReader reader, final VersionCreator versionCreator, final Map<String, DataEncryption> dataEncrypters) {
       
        final String oidStr = reader.readOid();
        final RootOid rootOid = getOidMarshaller().unmarshal(oidStr, RootOid.class);
       
        final ObjectAdapter adapter = getAdapter(rootOid);
        if (adapter.isResolved()) {
            Version version = null;
            final String versionString = reader.readVersion();
            if (!versionString.equals("")) {
                final String user = reader.readUser();
                final String time = reader.readTime();
                version = versionCreator.version(versionString, user, time);
            }
            if (version.different(adapter.getVersion())) {
                // TODO - do we need to CHECK version and update
                LOG.warn("while reading data into " + oidStr + " version was " + version + " when existing adapter was already " + adapter.getVersion());
            }
           
        } else {
           
            // TODO move lock to common method
            // object.setOptimisticLock(version);
            loadState(reader, versionCreator, dataEncrypters, adapter);
        }

        return adapter;
    }

    public void update(final StateReader reader, final VersionCreator versionCreator, final Map<String, DataEncryption> dataEncrypters, final ObjectAdapter object) {
        loadState(reader, versionCreator, dataEncrypters, object);
    }

    private void loadState(final StateReader reader, final VersionCreator versionCreator, final Map<String, DataEncryption> dataEncrypters, final ObjectAdapter object) {
        final ResolveState resolveState = ResolveState.RESOLVING;
        object.changeState(resolveState);
        Version version = null;
        final String versionString = reader.readVersion();
        if (!versionString.equals("")) {
            final String user = reader.readUser();
            final String time = reader.readTime();
            version = versionCreator.version(versionString, user, time);
        }
        final String encryptionType = reader.readEncrytionType();
        readFields(reader, object, dataEncrypters.get(encryptionType));
        object.setVersion(version);
        object.changeState(resolveState.getEndState());
    }

    private void readFields(final StateReader reader, final ObjectAdapter object, final DataEncryption dataEncrypter) {
        final ObjectAssociationContainer specification = object.getSpecification();
        final List<ObjectAssociation> associations = specification.getAssociations(Contributed.EXCLUDED);
        for (final ObjectAssociation association : associations) {
            if (association.isNotPersisted()) {
                continue;
            }
            if (association.isOneToManyAssociation()) {
                readCollection(reader, dataEncrypter, (OneToManyAssociation) association, object);
            } else if (association.getSpecification().isValue()) {
                readValue(reader, dataEncrypter, (OneToOneAssociation) association, object);
            } else if (association.getSpecification().isParented()) {
                readAggregate(reader, dataEncrypter, (OneToOneAssociation) association, object);
            } else {
                readReference(reader, (OneToOneAssociation) association, object);
            }
        }
    }

    private void readAggregate(final StateReader reader, final DataEncryption dataEncrypter, final OneToOneAssociation association, final ObjectAdapter parentAdapter) {
        final String id = association.getId();
        final StateReader aggregateReader = reader.readAggregate(id);
       
        final ObjectAdapter fieldObject;
        if (aggregateReader != null) {
            final String oidStr = aggregateReader.readOid();
            final AggregatedOid aggregatedOid = getOidMarshaller().unmarshal(oidStr, AggregatedOid.class);
            fieldObject = restoreAggregatedObject(aggregateReader, aggregatedOid, dataEncrypter);
        } else {
            fieldObject = null;
        }
       
        association.initAssociation(parentAdapter, fieldObject);
    }

    private ObjectAdapter restoreAggregatedObject(final StateReader aggregateReader, final AggregatedOid aggregatedOid, final DataEncryption dataEncrypter) {
        final ObjectAdapter fieldObject = getAdapter(aggregatedOid);
        final ResolveState resolveState = ResolveState.RESOLVING;
        fieldObject.changeState(resolveState);
        readFields(aggregateReader, fieldObject, dataEncrypter);
        fieldObject.changeState(resolveState.getEndState());

        return fieldObject;
    }

    private void readValue(final StateReader reader, final DataEncryption dataEncrypter, final OneToOneAssociation association, final ObjectAdapter object) {
        final String fieldData = reader.readField(association.getId());
        if (fieldData != null) {
            if (fieldData.equals("null")) {
                association.initAssociation(object, null);
            } else {
                final EncodableFacet encodeableFacet = association.getSpecification().getFacet(EncodableFacet.class);
                final String decryptedData = dataEncrypter.decrypt(fieldData);
                final ObjectAdapter value = encodeableFacet.fromEncodedString(decryptedData);
                association.initAssociation(object, value);
            }
        }
    }

    private void readReference(final StateReader reader, final OneToOneAssociation association, final ObjectAdapter object) {
        ObjectAdapter fieldObject;
        final String ref = reader.readField(association.getId());
        if (ref == null || ref.equals("null")) {
            fieldObject = null;
        } else {
            if (ref.equals("")) {
                throw new NoSqlStoreException("Invalid reference field (an empty string) in data for " + association.getName() + "  in " + object);
            }
            final RootOid oid = keyCreator.unmarshal(ref);
            fieldObject = getAdapter(oid);
        }
        try {
            association.initAssociation(object, fieldObject);
        } catch (IllegalArgumentException e) {
            throw new NoSqlStoreException("Failed to process field data for " + association.getName() + "  in " + object + ": " + ref);
        }
    }

    private void readCollection(final StateReader reader, final DataEncryption dataEncrypter, final OneToManyAssociation association, final ObjectAdapter parentAdapter) {
        final ObjectAdapter collectionAdapter = association.get(parentAdapter);
       
        final CollectionFacet facet = collectionAdapter.getSpecification().getFacet(CollectionFacet.class);
        if (association.getSpecification().isParented()) {
            // were persisted inline, so read back inline
            final List<StateReader> readers = reader.readCollection(association.getId());
            final ObjectAdapter[] elementAdapters = new ObjectAdapter[readers.size()];
            int i = 0;
            for (final StateReader elementReader : readers) {
               
                final String oidStr = elementReader.readOid();
                final AggregatedOid aggregatedOid = getOidMarshaller().unmarshal(oidStr, AggregatedOid.class);
               
                elementAdapters[i++] = restoreAggregatedObject(elementReader, aggregatedOid, dataEncrypter);
            }
            facet.init(collectionAdapter, elementAdapters);
        } else {
            // were persisted as references, so read back as references
            final String referencesList = reader.readField(association.getId());
            if (referencesList == null || referencesList.length() == 0) {
                facet.init(collectionAdapter, new ObjectAdapter[0]);
            } else {
                final ObjectAdapter[] elements = restoreElements(referencesList);
                facet.init(collectionAdapter, elements);
            }
        }
    }

    private ObjectAdapter[] restoreElements(final String referencesList) {
        final String[] references = referencesList.split("\\|");
        final ObjectAdapter[] elements = new ObjectAdapter[references.length];
        for (int i = 0; i < references.length; i++) {
           
            // no longer used
            //final ObjectSpecification specification = keyCreator.specificationFromOidStr(references[i]);
           
            final RootOid oid = keyCreator.unmarshal(references[i]);
            elements[i] = getAdapter(oid);
        }
        return elements;
    }

    protected ObjectAdapter getAdapter(final TypedOid oid) {
        return getAdapterManager().adapterFor(oid);
    }

   
    ////////////////////////////////////////////////////////////////////////////
    // dependencies (from context)
    ////////////////////////////////////////////////////////////////////////////
   
    protected Persistor getPersistenceSession() {
      return IsisContext.getPersistenceSession();
    }
   
    protected AdapterManager getAdapterManager() {
        return getPersistenceSession().getAdapterManager();
    }

    protected SpecificationLoaderSpi getSpecificationLoader() {
        return IsisContext.getSpecificationLoader();
    }

    protected OidMarshaller getOidMarshaller() {
        return IsisContext.getOidMarshaller();
    }

}
TOP

Related Classes of org.apache.isis.objectstore.nosql.ObjectReader

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.