com.ikanow.infinit.e.api.knowledge.aliases.AliasLookupTable.java Source code

Java tutorial

Introduction

Here is the source code for com.ikanow.infinit.e.api.knowledge.aliases.AliasLookupTable.java

Source

/*******************************************************************************
 * Copyright 2012, The Infinit.e Open Source Project.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 * 
 * This program 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package com.ikanow.infinit.e.api.knowledge.aliases;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.ikanow.infinit.e.data_model.store.document.EntityPojo;
import com.ikanow.infinit.e.data_model.store.feature.entity.EntityFeaturePojo;
import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo;
import com.ikanow.infinit.e.data_model.utils.DimensionUtility;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

public class AliasLookupTable {

    private static final Logger logger = Logger.getLogger(AliasLookupTable.class);

    /////////////////////////////////

    // Builds the Alias Lookup from a set of sources

    public synchronized void buildOrUpdateAliasTable(List<SharePojo> aliasTables, String userIdStr) {
        _aliasTable.clear();
        _reverseAliasTable.clear();

        _lastModified = new Date();

        _nNumAliasShares = 0;
        SharePojo personalShare = null;
        for (SharePojo share : aliasTables) {
            // Look for personal shares, apply them last
            if ((null != share.getCommunities()) && !share.getCommunities().isEmpty()) {
                SharePojo.ShareCommunityPojo primaryShareComm = share.getCommunities().iterator().next();
                if (null != primaryShareComm.get_id()) {
                    if (userIdStr.equalsIgnoreCase(primaryShareComm.get_id().toString())) {
                        personalShare = share; // (save and carry on) 
                        continue;
                    }
                }
            } //end look for personal community

            _nNumAliasShares++;
            populateAliasTableFromShare(share);
        }
        if (null != personalShare) { // Apply personal shares last
            _nNumAliasShares++;
            populateAliasTableFromShare(personalShare);
        }

    } //TESTED

    // Utility:

    private void populateAliasTableFromShare(SharePojo share) {
        String json = share.getShare();
        if (null != json) {
            try {
                DBObject dbo = (DBObject) JSON.parse(json);
                if (null != dbo) {
                    for (Object entryObj : dbo.toMap().entrySet()) {
                        @SuppressWarnings("unchecked")
                        Map.Entry<String, Object> entry = (Map.Entry<String, Object>) entryObj;

                        String masterAlias = entry.getKey();
                        EntityPojo masterAliasEntity = new EntityPojo();
                        masterAliasEntity.setIndex(masterAlias);

                        BasicDBObject entityFeatureObj = (BasicDBObject) entry.getValue();
                        EntityFeaturePojo aliasInfo = null;
                        try {
                            aliasInfo = EntityFeaturePojo.fromDb(entityFeatureObj, EntityFeaturePojo.class);
                        } catch (Exception e) {
                            logger.debug("Failed to deserialize aliasInfo", e);
                        }

                        if (masterAlias.endsWith("/")) { // it's a regex
                            try {
                                Pattern key = Pattern.compile(masterAlias.substring(0, masterAlias.length() - 1));
                                if (null == _entityRegexes) {
                                    _entityRegexes = new HashMap<Pattern, EntityFeaturePojo>();
                                }
                                _entityRegexes.put(key, aliasInfo);
                            } catch (Exception e) {
                            } // ignore regex compile fails
                            continue;
                        }

                        if ((null != aliasInfo) && (null != aliasInfo.getAlias())) {
                            aliasInfo.setIndex(masterAlias);
                            if ((null == aliasInfo.getDimension()) && (null != aliasInfo.getType())) {
                                aliasInfo.setDimension(DimensionUtility.getDimensionByType(aliasInfo.getType()));
                            } //TESTED

                            logger.debug("aliasTable entry: " + aliasInfo.getIndex() + " vs "
                                    + Arrays.toString(aliasInfo.getAlias().toArray()));

                            // This is going to collide in an ugly fashion across multiple communities, 
                            // we just have to live with that
                            for (String aliasIndex : aliasInfo.getAlias()) {
                                _aliasTable.put(aliasIndex, aliasInfo);
                            }
                            _aliasTable.put(aliasInfo.getIndex(), aliasInfo);
                            EntityFeaturePojo currAlias = _reverseAliasTable.get(aliasInfo.getIndex());
                            if (null == currAlias) {
                                _reverseAliasTable.put(aliasInfo.getIndex(), aliasInfo);
                            } else { // Collision ... this we can handle a little-bit more elegantly
                                currAlias.getAlias().addAll(aliasInfo.getAlias());
                                _reverseAliasTable.put(aliasInfo.getIndex(), currAlias);
                            }
                        }
                    }
                }
            } catch (Exception e) {
                logger.debug("General Aliasing Error: ", e);

            } // not Json, just carry on...
        }
    }//TESTED

    /////////////////////////////////

    // Returns relevant info
    // (for now only care about disname and index)

    public synchronized EntityFeaturePojo getAliasMaster(String index) { // returns master from alias or master indexes
        return _aliasTable.get(index);
    }

    public synchronized EntityFeaturePojo getAliases(String index) { // returns master from master index only

        if (null != _entityRegexes)
            for (Map.Entry<Pattern, EntityFeaturePojo> regexKV : _entityRegexes.entrySet()) {
                Matcher m = regexKV.getKey().matcher(index);
                if (m.matches()) {
                    EntityFeaturePojo dynamicAlias = new EntityFeaturePojo();
                    EntityFeaturePojo dynamicTemplate = regexKV.getValue();
                    if ((null != dynamicTemplate.getSemanticLinks())
                            && !dynamicTemplate.getSemanticLinks().isEmpty()) {
                        dynamicAlias.addToSemanticLinks(
                                new ArrayList<String>(dynamicTemplate.getSemanticLinks().size()));
                        for (String s : dynamicTemplate.getSemanticLinks()) {
                            for (int i = 1; i <= m.groupCount(); ++i) {
                                s = s.replaceAll("\\$0+" + i, m.group(i));
                            }
                            dynamicAlias.getSemanticLinks().add(s);
                        }
                    }
                    if (null != dynamicTemplate.getAlias()) {
                        for (String s : dynamicTemplate.getAlias()) {
                            for (int i = 1; i <= m.groupCount(); ++i) {
                                s = s.replaceAll("\\$0+" + i, m.group(i));
                            }
                            dynamicAlias.addAlias(s);
                        }
                    }
                    return dynamicAlias;
                }
            } //TESTED (both alias and semantic links) 

        return _reverseAliasTable.get(index);
    }

    public synchronized Collection<EntityFeaturePojo> masters() {
        return _reverseAliasTable.values();
    }
    /////////////////////////////////

    // Return last update time (null for never)

    public synchronized Date getLastModified() {
        return _lastModified;
    }

    public synchronized int getNumAliasShares() {
        return _nNumAliasShares;
    }

    /////////////////////////////////

    // Update modified time (if not modified)

    public synchronized void setLastModified(Date lastChecked) {
        _lastModified = lastChecked;
    }

    /////////////////////////////////

    // Returns true if the table is actually empty

    public synchronized boolean isEmpty() {
        return _aliasTable.isEmpty();
    }

    ////////////////////////////////////////////////////////////////////////////////////////////

    // State:

    private int _nNumAliasShares = 0;
    private Date _lastModified = null;
    private HashMap<String, EntityFeaturePojo> _aliasTable = new HashMap<String, EntityFeaturePojo>();
    private HashMap<String, EntityFeaturePojo> _reverseAliasTable = new HashMap<String, EntityFeaturePojo>();
    private HashMap<Pattern, EntityFeaturePojo> _entityRegexes = null;

}