fr.gouv.vitam.cbes.ResultCached.java Source code

Java tutorial

Introduction

Here is the source code for fr.gouv.vitam.cbes.ResultCached.java

Source

/**
 * This file is part of POC MongoDB ElasticSearch Project.
 *
 * Copyright 2009, Frederic Bregier, and individual contributors by the @author
 * tags. See the COPYRIGHT.txt in the distribution for a full listing of
 * individual contributors.
 *
 * All POC MongoDB ElasticSearch Project is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * POC MongoDB ElasticSearch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with POC MongoDB ElasticSearch . If not, see <http://www.gnu.org/licenses/>.
 */
package fr.gouv.vitam.cbes;

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

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

import fr.gouv.vitam.cbes.CouchbaseAccess.VitamCollections;
import fr.gouv.vitam.utils.UUID;

/**
 * Result (potentially cached) object
 *
 * @author "Frederic Bregier"
 *
 */
public class ResultCached extends VitamType {
    /**
     * Current SAip in the result
     */
    public static final String CURRENTDAIP = "__cdaip";
    /**
     * Min depth
     */
    public static final String MINLEVEL = "__min";
    /**
     * Max depth
     */
    public static final String MAXLEVEL = "__max";
    /**
     * Number of sub nodes
     */
    public static final String NBSUBNODES = "__nbnd";

    /**
     * Current SAip in the result
     */
    public Set<String> currentDaip = new HashSet<String>();
    /**
     * Min depth
     */
    public int minLevel = 0;
    /**
     * Max depth
     */
    public int maxLevel = 0;
    /**
     * Number of sub nodes
     */
    public long nbSubNodes = -1;
    /**
     * If loaded (or saved) to the database = True
     */
    public boolean loaded = false;

    /**
     *
     */
    public ResultCached() {

    }

    /**
     * @param collection
     */
    public ResultCached(final Collection<String> collection) {
        currentDaip.addAll(collection);
        updateMinMax();
        // Path list so as loaded (never cached)
        loaded = true;
        putBeforeSave();
    }

    @Override
    public void clear() {
        super.clear();
        currentDaip.clear();
        minLevel = 0;
        maxLevel = 0;
        nbSubNodes = -1;
        loaded = false;
    }

    @Override
    public void getAfterLoad() {
        super.getAfterLoad();
        if (containsField(CURRENTDAIP)) {
            @SuppressWarnings("unchecked")
            final Set<String> list = (Set<String>) this.get(CURRENTDAIP);
            currentDaip.clear();
            currentDaip.addAll(list);
        }
        if (this.containsField(MINLEVEL)) {
            minLevel = this.getInt(MINLEVEL);
        } else {
            minLevel = 0;
        }
        if (this.containsField(MAXLEVEL)) {
            maxLevel = this.getInt(MAXLEVEL);
        } else {
            maxLevel = 0;
        }
        if (this.containsField(NBSUBNODES)) {
            nbSubNodes = this.getLong(NBSUBNODES);
        } else {
            nbSubNodes = -1;
        }
    }

    @Override
    public void putBeforeSave() {
        super.putBeforeSave();
        if (!currentDaip.isEmpty()) {
            put(CURRENTDAIP, currentDaip);
        }
        put(MINLEVEL, minLevel);
        put(MAXLEVEL, maxLevel);
        put(NBSUBNODES, nbSubNodes);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected boolean updated(final CouchbaseAccess dbvitam) {
        final ResultCached vt = (ResultCached) dbvitam.findOne(VitamCollections.Crequests, getId());
        if (vt != null) {
            final List<DBObject> list = new ArrayList<DBObject>();
            final List<String> slist = (List<String>) vt.get(CURRENTDAIP);
            if (slist != null) {
                final Set<String> newset = new HashSet<String>(currentDaip);
                newset.removeAll(currentDaip);
                if (!newset.isEmpty()) {
                    list.add(new BasicDBObject(CURRENTDAIP, new BasicDBObject("$each", newset)));
                }
            }
            if (!list.isEmpty()) {
                final BasicDBObject upd = new BasicDBObject();
                for (final DBObject dbObject : list) {
                    upd.putAll(dbObject);
                }
                upd.append(MINLEVEL, minLevel);
                upd.append(MAXLEVEL, maxLevel);
                upd.append(NBSUBNODES, nbSubNodes);
                final BasicDBObject update = new BasicDBObject("$addToSet", upd);
                // XXX FIXME cannot make an update
                //dbvitam.requests.collection.update(new BasicDBObject(ID, this.get(ID)), update);
            }
        }
        return false;
    }

    @Override
    public void save(final CouchbaseAccess dbvitam) {
        putBeforeSave();
        if (updated(dbvitam)) {
            return;
        }
        updateOrSave(dbvitam.requests);
        loaded = true;
    }

    @Override
    public void load(final CouchbaseAccess dbvitam) {
        final ResultCached vt = (ResultCached) dbvitam.findOne(VitamCollections.Crequests, getId());
        this.putAll(vt);
        loaded = true;
    }

    /**
     * Compute min and max from list of UUID in currentMaip.
     * Note: this should not be called from a list of "short" UUID, but only with "path" UUIDs
     */
    public void updateMinMax() {
        minLevel = 0;
        maxLevel = 0;
        for (final String id : currentDaip) {
            final int level = UUID.getUuidNb(id);
            if (minLevel > level) {
                minLevel = level;
            }
            if (maxLevel == 0 || maxLevel < level) {
                maxLevel = level;
            }
        }
    }

    /**
     * Compute min and max from list of real MAIP (from UUID), so loaded from database (could be heavy)
     *
     * @param dbvitam
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public void updateLoadMinMax(final CouchbaseAccess dbvitam)
            throws InstantiationException, IllegalAccessException {
        minLevel = 0;
        maxLevel = 0;
        for (final String id : currentDaip) {
            int level = UUID.getUuidNb(id);
            if (UUID.getUuidNb(id) == 1) {
                final DAip daip = DAip.findOne(dbvitam, id);
                if (daip == null) {
                    continue;
                }
                final Map<String, Integer> domdepth = daip.getDomDepth();
                if (domdepth == null || domdepth.isEmpty()) {
                    level = 1;
                } else {
                    level = Integer.MAX_VALUE;
                    for (final int lev : domdepth.values()) {
                        if (level > lev) {
                            level = lev;
                        }
                    }
                    level++;
                }
            }
            if (minLevel > level) {
                minLevel = level;
            }
            if (maxLevel == 0 || maxLevel < level) {
                maxLevel = level;
            }
        }
    }

    /**
     * @param mdAccess
     *            if null, this method returns always True (simulate)
     * @param next
     * @return True if this contains ancestors for next current
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public boolean checkAncestor(final CouchbaseAccess mdAccess, final ResultCached next)
            throws InstantiationException, IllegalAccessException {
        if (mdAccess == null) {
            return true;
        }
        final Set<String> previousLastSet = new HashSet<String>();
        // Compute last Id from previous result
        for (final String id : currentDaip) {
            previousLastSet.add(UUID.getLastAsString(id));
        }
        final Map<String, List<String>> nextFirstMap = new HashMap<String, List<String>>();
        // Compute first Id from current result
        for (final String id : next.currentDaip) {
            List<String> list = nextFirstMap.get(UUID.getFirstAsString(id));
            if (list == null) {
                list = new ArrayList<String>();
                nextFirstMap.put(UUID.getFirstAsString(id), list);
            }
            list.add(id);
        }
        final Map<String, List<String>> newMap = new HashMap<String, List<String>>(nextFirstMap);
        for (final String id : nextFirstMap.keySet()) {
            final DAip aip = DAip.findOne(mdAccess, id);
            if (aip == null) {
                continue;
            }
            final Map<String, Integer> fathers = aip.getDomDepth();
            final Set<String> fathersIds = fathers.keySet();
            // Check that parents of First Ids of Current result contains Last Ids from Previous result
            fathersIds.retainAll(previousLastSet);
            if (fathers.isEmpty()) {
                // issue there except if First = Last
                if (previousLastSet.contains(id)) {
                    continue;
                }
                newMap.remove(id);
            }
        }
        next.currentDaip.clear();
        for (final List<String> list : newMap.values()) {
            next.currentDaip.addAll(list);
        }
        next.putBeforeSave();
        return !next.currentDaip.isEmpty();
    }

    protected static void addIndexes(final CouchbaseAccess mongoDbAccess) {
        // dbvitam.requests.collection.createIndex(new BasicDBObject(MongoDbAccess.VitamLinks.DAip2PAip.field2to1, 1));
    }
}