1 /* 2 * Copyright 2008-2010 smartics, Kronseder & Reiner GmbH 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 de.smartics.maven.issues.cache; 18 19 import java.io.File; 20 import java.util.HashMap; 21 import java.util.Map; 22 import java.util.WeakHashMap; 23 24 import org.apache.commons.logging.Log; 25 import org.apache.commons.logging.LogFactory; 26 import org.eclipse.mylyn.tasks.core.data.TaskData; 27 28 /** 29 * Local cache for task data retrieved from the remote Task repository. The 30 * cache is useful for multi project reports where the same tasks will be 31 * retrieved for each sub project. Instead of connecting to the remote 32 * repository the report renderer will try to read the local stored information. 33 * This information is either cached in-memory or on a secondary storage medium 34 * (defaults to an XML file on the file system). 35 * 36 * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a> 37 * @version $Revision:591 $ 38 */ 39 public class TaskDataCache 40 { 41 // ********************************* Fields ********************************* 42 43 // --- constants ------------------------------------------------------------ 44 45 /** 46 * Reference to the logger for this class. 47 */ 48 private final Log log = LogFactory.getLog(TaskDataCache.class); 49 50 // --- members -------------------------------------------------------------- 51 52 /** 53 * The in-memory cache of the {@link TaskData tasks} fetched from the remote 54 * repository. 55 * <p> 56 * The key is the unique identifier of the task, the value the task 57 * information. 58 * </p> 59 */ 60 private final Map<String, TaskData> cache; 61 62 /** 63 * The storage handler to make task data instances persistent. The task store 64 * has a value of <code>null</code> if no persistent store is used (i.e. 65 * <code>usePersistentStore</code> is <code>false</code>. 66 */ 67 private final TaskDataStore taskStore; 68 69 /** 70 * The flag to indicate whether to use a persistent store (<code>true</code>) 71 * or not (<code>false</code>). If the persistent store is used each task is 72 * stored to the specified path. 73 */ 74 private final boolean usePersistentStore; 75 76 // ****************************** Initializer ******************************* 77 78 // ****************************** Constructors ****************************** 79 80 /** 81 * Convenience constructor to create a cache where all tasks are stored 82 * in-memory. 83 */ 84 public TaskDataCache() 85 { 86 this((TaskDataStore) null); 87 } 88 89 /** 90 * Convenience constructor to create a file based task data store to write to 91 * the given location. 92 * 93 * @param persistentStoreDirectory the reference to the directory to store the 94 * individual task files. If this value is <code>null</code> the 95 * tasks will only be stored in-memory with a strong hash map. If 96 * not-<code>null</code>, a weak hash map is used and tasks that are 97 * removed from memory are written to this location. 98 */ 99 public TaskDataCache(final File persistentStoreDirectory) 100 { 101 this(persistentStoreDirectory != null ? new XmlTaskDataStore( 102 persistentStoreDirectory) : null); 103 } 104 105 /** 106 * Default constructor. 107 * 108 * @param taskStore the reference to the task store to store the individual 109 * task data. If this value is <code>null</code> the tasks will only 110 * be stored in-memory with a strong hash map. If not- 111 * <code>null</code>, a weak hash map is used and tasks that are 112 * removed from memory are written to this store. 113 */ 114 public TaskDataCache(final TaskDataStore taskStore) 115 { 116 this.usePersistentStore = (taskStore != null); 117 if (usePersistentStore) 118 { 119 this.taskStore = taskStore; 120 cache = new WeakHashMap<String, TaskData>(); 121 } 122 else 123 { 124 this.taskStore = null; 125 cache = new HashMap<String, TaskData>(); 126 } 127 } 128 129 // ****************************** Inner Classes ***************************** 130 131 // ********************************* Methods ******************************** 132 133 // --- init ----------------------------------------------------------------- 134 135 // --- get&set -------------------------------------------------------------- 136 137 // --- business ------------------------------------------------------------- 138 139 /** 140 * Returns the task uniquely references by the given identifier. 141 * 142 * @param id the unique identifier of the task. 143 * @return the requested task. 144 */ 145 public TaskData getTask(final String id) 146 { 147 TaskData task = cache.get(id); 148 if (task == null && usePersistentStore) 149 { 150 try 151 { 152 task = taskStore.load(id); 153 cache.put(id, task); 154 } 155 catch (final PersistenceException e) 156 { 157 if (log.isDebugEnabled()) 158 { 159 log.debug("Cannot load task '" + id + "' from persistency layer.", e); 160 } 161 } 162 } 163 return task; 164 } 165 166 /** 167 * Adds the task to the cache. The task can be retrieved by 168 * {@link #getTask(String)} by passing in the identifier of the task ( 169 * {@link TaskData#getTaskId()}). 170 * 171 * @param task the task information to cache. 172 */ 173 public void addTask(final TaskData task) 174 { 175 final String id = task.getTaskId(); 176 cache.put(id, task); 177 if (usePersistentStore) 178 { 179 try 180 { 181 taskStore.persist(task); 182 } 183 catch (final PersistenceException e) 184 { 185 if (log.isDebugEnabled()) 186 { 187 log.debug("Cannot persist task '" + id + "'.", e); 188 } 189 } 190 } 191 } 192 193 // --- object basics -------------------------------------------------------- 194 195 }