Package org.apache.isis.objectstore.nosql.db.mongo

Source Code of org.apache.isis.objectstore.nosql.db.mongo.MongoDb

/*
*  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.db.mongo;

import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.List;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

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

import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
import org.apache.isis.core.metamodel.spec.feature.Contributed;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommand;
import org.apache.isis.objectstore.nosql.NoSqlCommandContext;
import org.apache.isis.objectstore.nosql.NoSqlStoreException;
import org.apache.isis.objectstore.nosql.db.NoSqlDataDatabase;
import org.apache.isis.objectstore.nosql.db.StateReader;
import org.apache.isis.objectstore.nosql.db.StateWriter;
import org.apache.isis.objectstore.nosql.keys.KeyCreatorDefault;

public class MongoDb implements NoSqlDataDatabase {

  private static final String SERIALNUMBERS_COLLECTION_NAME = "serialnumbers";

  private static final Logger LOG = LoggerFactory.getLogger(MongoDb.class);
 
  private static final int DEFAULT_PORT = 27017;

    private final String host;
    private final int port;
    private final String dbName;
    private final KeyCreatorDefault keyCreator;
   
  private Mongo mongo;
  private DB db;

    public MongoDb(final String host, final int port, final String name, final KeyCreatorDefault keyCreator) {
        this.host = host;
        this.port = port == 0 ? DEFAULT_PORT : port;
        this.dbName = name;
        this.keyCreator = keyCreator;
    }

    public KeyCreatorDefault getKeyCreator() {
        return keyCreator;
    }

    @Override
    public void open() {
        try {
            if (mongo == null) {
                mongo = new Mongo(host, port);
                db = mongo.getDB(dbName);
                db.setWriteConcern(com.mongodb.WriteConcern.SAFE);
                LOG.info("opened database (" + dbName + "): " + mongo);
            } else {
                LOG.info(" using opened database " + db);
            }
        } catch (final UnknownHostException e) {
            throw new NoSqlStoreException(e);
        } catch (final MongoException e) {
            throw new NoSqlStoreException(e);
        }
    }

    @Override
    public void close() {
    }

    public NoSqlCommandContext createTransactionContext() {
        return null;
    }

    //////////////////////////////////////////////////
    // contains data
    //////////////////////////////////////////////////

    @Override
    public boolean containsData() {
        return db.getCollectionNames().size() > 0;
    }

   
    //////////////////////////////////////////////////
    // serial numbers
    //////////////////////////////////////////////////
   
    @Override
    public long nextSerialNumberBatch(final ObjectSpecId name, final int batchSize) {
        long next = readSerialNumber();
        writeSerialNumber(next + batchSize);
        return next + 1;
    }

    private void writeSerialNumber(final long serialNumber) {
        final DBCollection system = db.getCollection(SERIALNUMBERS_COLLECTION_NAME);
        DBObject object = system.findOne();
        if (object == null) {
            object = new BasicDBObject();
        }
        object.put("next-id", Long.toString(serialNumber));
        system.save(object);
        LOG.info("serial number written: " + serialNumber);
    }

    private long readSerialNumber() {
        final DBCollection system = db.getCollection(SERIALNUMBERS_COLLECTION_NAME);
        final DBObject data = system.findOne();
        if (data == null) {
            return 0;
        } else {
            final String number = (String) data.get("next-id");
            LOG.info("serial number read: " + number);
            return Long.valueOf(number);
        }
    }

    //////////////////////////////////////////////////
    // hasInstances, instancesOf
    //////////////////////////////////////////////////

    @Override
    public boolean hasInstances(final ObjectSpecId objectSpecId) {
        final DBCollection instances = db.getCollection(objectSpecId.asString());
        return instances.getCount() > 0;
    }

    @Override
    public Iterator<StateReader> instancesOf(final ObjectSpecId objectSpecId) {
        final DBCollection instances = db.getCollection(objectSpecId.asString());
        final DBCursor cursor = instances.find();
        LOG.info("searching for instances of: " + objectSpecId);
        return new Iterator<StateReader>() {
            @Override
            public boolean hasNext() {
                return cursor.hasNext();
            }

            @Override
            public StateReader next() {
                return new MongoStateReader(cursor.next());
            }

            @Override
            public void remove() {
                throw new NoSqlStoreException("Can't remove elements");
            }

        };
    }
   
    @Override
    public Iterator<StateReader> instancesOf(ObjectSpecId objectSpecId, ObjectAdapter pattern) {
        final DBCollection instances = db.getCollection(objectSpecId.asString());

        // REVIEW check the right types are used in matches
        final BasicDBObject query = new BasicDBObject();
        for ( ObjectAssociation association  : pattern.getSpecification().getAssociations(Contributed.EXCLUDED)) {
            ObjectAdapter field = association.get(pattern);
            if (!association.isEmpty(pattern)) {
                if (field.isValue()) {
                    query.put(association.getIdentifier().getMemberName(), field.titleString());
                } else if (association.isOneToOneAssociation()) {
                    query.put(association.getIdentifier().getMemberName(), field.getOid());
                }
            }
        }
        final DBCursor cursor = instances.find(query);
        LOG.info("searching for instances of: " + objectSpecId);
        return new Iterator<StateReader>() {
            @Override
            public boolean hasNext() {
                return cursor.hasNext();
            }

            @Override
            public StateReader next() {
                return new MongoStateReader(cursor.next());
            }

            @Override
            public void remove() {
                throw new NoSqlStoreException("Can't remove elements");
            }

        };
    }

    @Override
    public StateReader getInstance(final String key, final ObjectSpecId objectSpecId) {
        return new MongoStateReader(db, objectSpecId, key);
    }

    //////////////////////////////////////////////////
    // write, delete
    //////////////////////////////////////////////////

    public StateWriter createStateWriter(final ObjectSpecId objectSpecId) {
        return new MongoStateWriter(db, objectSpecId);
    }


    @Override
    public void write(final List<PersistenceCommand> commands) {
        final NoSqlCommandContext context = new MongoClientCommandContext(db);
        for (final PersistenceCommand command : commands) {
            command.execute(context);
        }
    }


    //////////////////////////////////////////////////
    // services
    //////////////////////////////////////////////////

    @Override
    public void addService(final ObjectSpecId objectSpecId, final String key) {
        final DBCollection services = db.getCollection("services");
        services.insert(new BasicDBObject().append("name", objectSpecId.asString()).append("key", key));
        LOG.info("service added " + objectSpecId + ":" + key);
    }

    @Override
    public String getService(final ObjectSpecId objectSpecId) {
        final DBCollection services = db.getCollection("services");
        final DBObject object = services.findOne(new BasicDBObject().append("name", objectSpecId.asString()));
        if (object == null) {
            return null;
        } else {
            final String id = (String) object.get("key");
            LOG.info("service found " + objectSpecId + ":" + id);
            return id;
        }
    }
}
TOP

Related Classes of org.apache.isis.objectstore.nosql.db.mongo.MongoDb

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.