Typo in log msg.
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / artifact / provider / MemoryArtifactMapper.java
1 /*
2  * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package edu.internet2.middleware.shibboleth.artifact.provider;
18
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.Map.Entry;
26
27 import org.apache.log4j.Logger;
28 import org.opensaml.artifact.Artifact;
29 import org.w3c.dom.Element;
30
31 import edu.internet2.middleware.shibboleth.artifact.ArtifactMapper;
32 import edu.internet2.middleware.shibboleth.artifact.ArtifactMapping;
33 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
34
35 /**
36  * <code>ArtifactMapper</code> implementation that saves queryable artifacts in memory.
37  * 
38  * @author Walter Hoehn
39  */
40 public class MemoryArtifactMapper extends BaseArtifactMapper implements ArtifactMapper {
41
42         private MemoryArtifactCleaner cleaner = new MemoryArtifactCleaner();
43         private static Logger log = Logger.getLogger(MemoryArtifactMapper.class.getName());
44         private static Map mappings = Collections.synchronizedMap(new HashMap());
45
46         public MemoryArtifactMapper() throws ShibbolethConfigurationException {
47
48                 super();
49         }
50
51         public MemoryArtifactMapper(Element config) throws ShibbolethConfigurationException {
52
53                 super(config);
54         }
55
56         public ArtifactMapping recoverAssertion(Artifact artifact) {
57
58                 ArtifactMapping mapping = (ArtifactMapping) mappings.get(artifact);
59                 mappings.remove(artifact);
60                 if (mapping == null || mapping.isExpired()) { return null; }
61                 return mapping;
62         }
63
64         public void addAssertionImpl(Artifact artifact, ArtifactMapping mapping) {
65
66                 mappings.put(artifact, mapping);
67         }
68
69         protected void destroy() {
70
71                 synchronized (cleaner) {
72                         if (cleaner != null) {
73                                 cleaner.shutdown = true;
74                                 cleaner.interrupt();
75                         }
76                 }
77         }
78
79         protected void finalize() throws Throwable {
80
81                 super.finalize();
82                 destroy();
83         }
84
85         private class MemoryArtifactCleaner extends Thread {
86
87                 private boolean shutdown = false;
88                 private Thread master;
89
90                 public MemoryArtifactCleaner() {
91
92                         super("edu.internet2.middleware.shibboleth.idp.provider.MemoryArtifactMapper..MemoryArtifactCleaner");
93                         this.master = Thread.currentThread();
94                         setDaemon(true);
95                         if (getPriority() > Thread.MIN_PRIORITY) {
96                                 setPriority(getPriority() - 1);
97                         }
98                         log.debug("Starting memory-based artifact mapper cleanup thread.");
99                         start();
100                 }
101
102                 public void run() {
103
104                         try {
105                                 sleep(60 * 1000); // one minute
106                         } catch (InterruptedException e) {
107                                 log.debug("Memory-based artifact mapper cleanup interrupted.");
108                         }
109                         while (true) {
110                                 try {
111                                         if (!master.isAlive()) {
112                                                 shutdown = true;
113                                                 log.debug("Memory-based artifact mapper cleaner is orphaned.");
114                                         }
115                                         if (shutdown) {
116                                                 log.debug("Stopping Memory-based artifact mapper cleanup thread.");
117                                                 return;
118                                         }
119                                         log.debug("Memory-based artifact mapper cleanup thread searching for stale entries.");
120                                         Set needsDeleting = new HashSet();
121                                         synchronized (mappings) {
122                                                 Iterator iterator = mappings.entrySet().iterator();
123                                                 while (iterator.hasNext()) {
124                                                         Entry entry = (Entry) iterator.next();
125                                                         ArtifactMapping mapping = (ArtifactMapping) entry.getValue();
126                                                         if (mapping.isExpired()) {
127                                                                 needsDeleting.add(entry.getKey());
128                                                         }
129                                                 }
130                                                 // release the lock to be friendly
131                                                 Iterator deleteIterator = needsDeleting.iterator();
132                                                 while (deleteIterator.hasNext()) {
133                                                         synchronized (mappings) {
134                                                                 log.debug("Expiring an Artifact from the memory cache.");
135                                                                 mappings.remove(deleteIterator.next());
136                                                         }
137                                                 }
138                                         }
139                                         sleep(60 * 1000); // one minute
140                                 } catch (InterruptedException e) {
141                                         log.debug("Memory-based artifact mapper cleanup interrupted.");
142                                 }
143                         }
144                 }
145         }
146
147 }