Java tutorial
/******************************************************************************* * 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; }