1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.scenegraph;
\r
14 import java.util.HashMap;
\r
15 import java.util.Map;
\r
16 import java.util.logging.Level;
\r
17 import java.util.logging.Logger;
\r
20 * A synchronized reference implementation of {@link ILookupService}.
\r
22 * @author Tuukka Lehtonen
\r
24 public class LookupService implements ILookupService {
\r
26 private final Object lookupLock = new Object();
\r
27 private final Map<String, INode> toNode = new HashMap<String, INode>();
\r
28 private final Map<INode, String> toId = new HashMap<INode, String>();
\r
30 Logger logger = Logger.getLogger(getClass().getName());
\r
33 public INode map(String id, INode node) {
\r
35 throw new NullPointerException("null id");
\r
37 throw new NullPointerException("null node");
\r
41 synchronized (lookupLock) {
\r
42 oldNode = toNode.put(id, node);
\r
43 oldId = toId.put(node, id);
\r
45 // Keep the mapping a consistent bijection:
\r
46 // If ID => INode mapping is removed, the INode => ID mappings must
\r
49 if (oldNode != null && !oldNode.equals(node)) {
\r
50 String removedId = toId.remove(oldNode);
\r
51 if (!id.equals(removedId))
\r
52 toNode.remove(removedId);
\r
54 if (oldId != null && !oldId.equals(id)) {
\r
55 INode removedNode = toNode.remove(oldId);
\r
56 if (removedNode != node)
\r
57 toId.remove(removedNode);
\r
60 if (logger.isLoggable(Level.FINE))
\r
61 logger.fine("map(" + id + ", " + node + ")");
\r
62 if (oldNode != null || oldId != null) {
\r
63 if (logger.isLoggable(Level.INFO)) {
\r
64 logger.info("replaced mappings for ID " + oldId + " and node " + oldNode);
\r
71 public INode unmap(String id) {
\r
74 synchronized (lookupLock) {
\r
75 node = toNode.remove(id);
\r
78 mappedId = toId.remove(node);
\r
80 if (logger.isLoggable(Level.FINE))
\r
81 logger.fine("unmap(" + id + "): " + node);
\r
82 if (mappedId != null && !mappedId.equals(id)) {
\r
83 if (logger.isLoggable(Level.WARNING))
\r
84 logger.log(Level.WARNING, "mapping was out-of-sync: " + id + " => " + node + " & " + mappedId + " => " + node, new Exception("trace"));
\r
90 public String unmap(INode node) {
\r
93 synchronized (lookupLock) {
\r
94 id = toId.remove(node);
\r
97 mappedNode = toNode.remove(id);
\r
99 if (logger.isLoggable(Level.FINE))
\r
100 logger.fine("unmap(" + node + "): " + id);
\r
101 if (mappedNode != null && node != mappedNode) {
\r
102 if (logger.isLoggable(Level.WARNING))
\r
103 logger.log(Level.WARNING, "mapping was out-of-sync: " + node + " => " + id + " & " + id + " => " + mappedNode, new Exception("trace"));
\r
109 public INode lookupNode(String id) {
\r
110 synchronized (lookupLock) {
\r
111 return toNode.get(id);
\r
116 public String lookupId(INode node) {
\r
117 synchronized (lookupLock) {
\r
118 return toId.get(node);
\r