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