1 /* 2 * This file is a part of CAST project. 3 * (c) Copyright 2007, AGH University of Science & Technology 4 * https://caribou.iisg.agh.edu.pl/trac/cast 5 * 6 * Licensed under the Eclipse Public License, Version 1.0 (the "License"). 7 * You may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * http://www.eclipse.org/legal/epl-v10.html 10 */ 11 /* 12 * File: NodeIndexer.java 13 * Created: 2008-11-25 14 * Author: tmilos 15 * $Id: NodeIndexer.java 3408 2009-09-30 15:19:10Z tmilos $ 16 */ 17 18 package pl.edu.agh.cast.model.visual.backward; 19 20 import java.util.ArrayList; 21 import java.util.List; 22 23 import org.eclipse.core.runtime.IProgressMonitor; 24 import org.eclipse.core.runtime.NullProgressMonitor; 25 26 import pl.edu.agh.cast.common.collections.MultiMap; 27 import pl.edu.agh.cast.model.attributes.AttributeValue; 28 import pl.edu.agh.cast.model.attributes.NodeAttributeManager; 29 30 /** 31 * Class for indexing {@link Node}s based on the specified attribute. The type of nodes to index may be specified. 32 * 33 * If the indexing attribute is equal to {@link NodeAttributeManager#PERMANENT_ID} then the existing index of supplied 34 * {@link VisualModelCachingFactory} is used. 35 * 36 * @author AGH CAST Team 37 */ 38 public class NodeIndexer { 39 40 private MultiMap<Object, Node> nodeMap; 41 42 private VisualModelCachingFactory visualModelFactory; 43 44 private String attribute; 45 46 private String type; 47 48 private boolean isId = false; 49 50 /** 51 * Creates node indexer with index built based on {@link NodeAttributeManager#PERMANENT_ID} attribute. All types of 52 * nodes are indexed. 53 * 54 * @param visualModelFactory 55 * {@link VisualModelCachingFactory} that provides nodes 56 */ 57 public NodeIndexer(VisualModelCachingFactory visualModelFactory) { 58 this(visualModelFactory, NodeAttributeManager.PERMANENT_ID); 59 } 60 61 /** 62 * Creates node indexer with index built based on <code>attribute</code> attribute.All types of nodes are indexed. 63 * 64 * @param visualModelFactory 65 * {@link VisualModelCachingFactory} that provides nodes 66 * @param attribute 67 * name of the attribute to be used for indexing 68 */ 69 public NodeIndexer(VisualModelCachingFactory visualModelFactory, String attribute) { 70 this(visualModelFactory, attribute, null); 71 } 72 73 /** 74 * Creates node indexer with index built based on <code>attribute</code> attribute. Only nodes of type 75 * <code>type</code> are indexed. 76 * 77 * @param visualModelFactory 78 * {@link VisualModelCachingFactory} that provides nodes 79 * @param attribute 80 * name of the attribute to be used for indexing 81 * @param type 82 * type of nodes to index - if <code>null</code> then all types are considered 83 */ 84 public NodeIndexer(VisualModelCachingFactory visualModelFactory, String attribute, String type) { 85 this(visualModelFactory, attribute, type, new NullProgressMonitor()); 86 } 87 88 /** 89 * Creates node indexer with index built based on <code>attribute</code> attribute. Only nodes of type 90 * <code>type</code> are indexed. 91 * 92 * @param visualModelFactory 93 * {@link VisualModelCachingFactory} that provides nodes 94 * @param attribute 95 * name of the attribute to be used for indexing 96 * @param type 97 * type of nodes to index - if <code>null</code> then all types are considered 98 * @param monitor 99 * operation progress monitor 100 */ 101 public NodeIndexer(VisualModelCachingFactory visualModelFactory, String attribute, String type, 102 IProgressMonitor monitor) { 103 this.visualModelFactory = visualModelFactory; 104 this.attribute = attribute; 105 this.type = type; 106 // if the attribute is the ID then use VMCF index 107 if (NodeAttributeManager.PERMANENT_ID.equals(attribute)) { 108 isId = true; 109 monitor.worked(this.visualModelFactory.getNodeCount()); 110 } else { 111 isId = false; 112 // allowing duplicates results in better performance :> 113 nodeMap = new MultiMap<Object, Node>(true); 114 115 // create index 116 for (Node node : this.visualModelFactory.getNodes()) { 117 if (this.type == null || this.type.equals(node.getType())) { 118 AttributeValue value = node.getAttributeValue(this.attribute); 119 if (value != null && value.getValue() != null) { 120 nodeMap.put(value.getValue(), node); 121 } 122 } 123 monitor.worked(1); 124 } 125 } 126 } 127 128 /** 129 * Wraps <code>node</code> into a list. If <code>node</code> is <code>null</code> then <code>null</code> is 130 * returned. 131 * 132 * @param node 133 * node to wrap 134 * @return a list containing the node (if it's not <code>null</code>) 135 */ 136 private List<Node> enlistNode(Node node) { 137 if (node == null) { 138 return null; 139 } 140 List<Node> nList = new ArrayList<Node>(1); 141 nList.add(node); 142 return nList; 143 } 144 145 /** 146 * Returns list of nodes that have the indexing attribute value equal to <code>value</code>. 147 * 148 * WARNING: in order to preserve performance, no validation on <code>value</code> type is performed 149 * 150 * @param value 151 * lookup value 152 * @return list of matching nodes 153 */ 154 public List<Node> lookup(Object value) { 155 if (isId) { 156 Node node = visualModelFactory.findNode((String)value); 157 // return if node type is allowed 158 if (node != null && (type == null || type.equals(node.getType()))) { 159 return enlistNode(node); 160 } else { 161 return null; 162 } 163 } else { 164 return nodeMap.get(value); 165 } 166 } 167 168 }