]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/LookupService.java
Safer URI unescaping for CSVFormatter subscription CSV exporter
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / LookupService.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph;
13
14 import java.util.HashMap;
15 import java.util.Map;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
18
19 /**
20  * A synchronized reference implementation of {@link ILookupService}.
21  * 
22  * @author Tuukka Lehtonen
23  */
24 public class LookupService implements ILookupService {
25
26     private final Object             lookupLock = new Object();
27     private final Map<String, INode> toNode     = new HashMap<String, INode>();
28     private final Map<INode, String> toId       = new HashMap<INode, String>();
29
30     Logger                     logger     = Logger.getLogger(getClass().getName());
31
32     @Override
33     public INode map(String id, INode node) {
34         if (id == null)
35             throw new NullPointerException("null id");
36         if (node == null)
37             throw new NullPointerException("null node");
38
39         INode oldNode;
40         String oldId;
41         synchronized (lookupLock) {
42             oldNode = toNode.put(id, node);
43             oldId = toId.put(node, id);
44
45             // Keep the mapping a consistent bijection:
46             // If ID => INode mapping is removed, the INode => ID mappings must
47             // removed also.
48
49             if (oldNode != null && !oldNode.equals(node)) {
50                 String removedId = toId.remove(oldNode);
51                 if (!id.equals(removedId))
52                     toNode.remove(removedId);
53             }
54             if (oldId != null && !oldId.equals(id)) {
55                 INode removedNode = toNode.remove(oldId);
56                 if (removedNode != node)
57                     toId.remove(removedNode);
58             }
59         }
60         if (logger.isLoggable(Level.FINE))
61             logger.fine("map(" + id + ", " + node + ")");
62         if (oldNode != null || oldId != null) {
63             if (logger.isLoggable(Level.INFO)) {
64                 logger.info("replaced mappings for ID " + oldId + " and node " + oldNode);
65             }
66         }
67         return oldNode;
68     }
69
70     @Override
71     public INode unmap(String id) {
72         INode node;
73         String mappedId;
74         synchronized (lookupLock) {
75             node = toNode.remove(id);
76             if (node == null)
77                 return null;
78             mappedId = toId.remove(node);
79         }
80         if (logger.isLoggable(Level.FINE))
81             logger.fine("unmap(" + id + "): " + node);
82         if (mappedId != null && !mappedId.equals(id)) {
83             if (logger.isLoggable(Level.WARNING))
84                 logger.log(Level.WARNING, "mapping was out-of-sync: " + id + " => " + node + " & " + mappedId + " => " + node, new Exception("trace"));
85         }
86         return node;
87     }
88
89     @Override
90     public String unmap(INode node) {
91         String id;
92         INode mappedNode;
93         synchronized (lookupLock) {
94             id = toId.remove(node);
95             if (node == null)
96                 return null;
97             mappedNode = toNode.remove(id);
98         }
99         if (logger.isLoggable(Level.FINE))
100             logger.fine("unmap(" + node + "): " + id);
101         if (mappedNode != null && node != mappedNode) {
102             if (logger.isLoggable(Level.WARNING))
103                 logger.log(Level.WARNING, "mapping was out-of-sync: " + node + " => " + id + " & " + id + " => " + mappedNode, new Exception("trace"));
104         }
105         return id;
106     }
107
108     @Override
109     public INode lookupNode(String id) {
110         synchronized (lookupLock) {
111             return toNode.get(id);
112         }
113     }
114
115     @Override
116     public String lookupId(INode node) {
117         synchronized (lookupLock) {
118             return toId.get(node);
119         }
120     }
121
122 }