View Javadoc

1   package com.atlassian.jira.issue.link;
2   
3   import java.util.ArrayList;
4   import java.util.Collections;
5   import java.util.Iterator;
6   import java.util.List;
7   import java.util.Map;
8   
9   import org.apache.commons.collections.map.LRUMap;
10  import org.apache.log4j.Logger;
11  import org.ofbiz.core.entity.EntityUtil;
12  import org.ofbiz.core.entity.GenericEntityException;
13  import org.ofbiz.core.entity.GenericValue;
14  
15  import com.atlassian.core.ofbiz.util.EntityUtils;
16  import com.atlassian.jira.config.ConstantsManager;
17  import com.atlassian.jira.permission.PermissionContextFactory;
18  import com.atlassian.jira.permission.PermissionTypeManager;
19  import com.atlassian.jira.project.ProjectManager;
20  import com.atlassian.jira.scheme.AbstractSchemeManager;
21  import com.atlassian.jira.scheme.SchemeEntity;
22  import com.atlassian.jira.scheme.SchemeFactory;
23  import com.atlassian.jira.util.map.EasyMap;
24  import com.opensymphony.user.User;
25  
26  /**
27   * FQCN : com.atlassian.jira.issue.link.DefaultLinkSchemeManager
28   * @author Kaamelot
29   * @since 3.10.30
30   * Description : Provides a default implementation of LinkSchemeManager
31   * - Manage Link Scheme Entities allowing to define authorized link between Issues
32   */
33  public class DefaultLinkSchemeManager extends AbstractSchemeManager implements LinkSchemeManager, LinkConstants {
34  
35  	private static final Logger log = Logger.getLogger(DefaultLinkSchemeManager.class);
36  
37  	protected ConstantsManager constantsManager; 
38  	protected IssueLinkTypeManager issueLinkTypeManager;
39  
40  	private Map cache;
41  
42  	public DefaultLinkSchemeManager(ProjectManager projectManager, PermissionTypeManager permissionTypeManager, PermissionContextFactory permissionContextFactory, SchemeFactory schemeFactory, ConstantsManager constantsManager, IssueLinkTypeManager issueLinkTypeManager) {
43  		super(projectManager, permissionTypeManager, permissionContextFactory, schemeFactory);
44  		this.constantsManager = constantsManager; 
45  		this.issueLinkTypeManager = issueLinkTypeManager;
46  		cache = Collections.synchronizedMap(new LRUMap(1000));
47  	}
48  
49  	/**
50  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getSchemeEntityName()
51  	 */
52  	public String getSchemeEntityName() {
53  		return SCHEME_ENTITY_NAME;
54  	}
55  
56  	/**
57  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getEntityName()
58  	 */
59  	public String getEntityName() {
60  		return ISSUE_TYPE_LINK_ENTITY_NAME;
61  	}
62  
63  	/**
64  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getAssociationType()
65  	 */
66  	public String getAssociationType() {
67  		return PROJECT_ASSOCIATION;
68  	}
69  
70  	/**
71  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getSchemeDesc()
72  	 */
73  	public String getSchemeDesc() {
74  		return SCHEME_DESC;
75  	}
76  
77  	/**
78  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#copySchemeEntity(org.ofbiz.core.entity.GenericValue, org.ofbiz.core.entity.GenericValue)
79  	 */
80  	public GenericValue copySchemeEntity(GenericValue scheme, GenericValue entity) throws GenericEntityException {
81  		SchemeEntity schemeEntity = new SchemeEntity(entity.getString(SCHEME_ENTITY_LINKTYPE), entity.getString(SCHEME_ENTITY_SOURCE), entity.getString(SCHEME_ENTITY_DESTINATION));
82  		return createSchemeEntity(scheme, schemeEntity);
83  	}
84  
85  	/**
86  	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#createSchemeEntity(org.ofbiz.core.entity.GenericValue, com.atlassian.jira.scheme.SchemeEntity)
87  	 */
88  	public GenericValue createSchemeEntity(GenericValue scheme, SchemeEntity schemeEntity) throws GenericEntityException {
89  		if (!(schemeEntity.getEntityTypeId() instanceof String))
90  			throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
91  
92  		try {
93  			Map fields = EasyMap.build(SCHEME_ENTITY_SCHEME, scheme.getLong(SCHEME_ID), 
94  						SCHEME_ENTITY_LINKTYPE, schemeEntity.getType(), 
95  						SCHEME_ENTITY_SOURCE, schemeEntity.getParameter(), 
96  						SCHEME_ENTITY_DESTINATION, schemeEntity.getEntityTypeId().toString());
97  			return EntityUtils.createValue(getEntityName(), fields);
98  		} finally {
99  			clearCache();
100 		}
101 	}
102 
103 	private void clearCache() {
104 		if (log.isDebugEnabled())
105 			log.debug("Clearing workflow scheme entity cache, had " + cache.size() + " entries");
106 
107 		cache.clear();
108 	}
109 
110 	/**
111 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getLinkSchemeEntities(org.ofbiz.core.entity.GenericValue)
112 	 */
113 	public List getLinkSchemeEntities(GenericValue scheme) throws GenericEntityException {
114 		String cacheKey = createCacheKey(scheme, null);
115 		List result = (List) cache.get(cacheKey);
116 
117 		if (result == null) {
118 			result = scheme.getRelated("Child" + getEntityName());
119 
120 			if (result == null)
121 				result = Collections.EMPTY_LIST;
122 
123 			if (log.isDebugEnabled())
124 				log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
125 
126 			cache.put(cacheKey, result);
127 		}
128 
129 		return result;
130 	}
131 	
132 	/**
133 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#toLinkSchemeEntityObjects(java.util.List)
134 	 */
135 	public List toLinkSchemeEntityObjects(List _schemeEntities)  {
136 		List schemeEntities = new ArrayList(); 
137 		for (Iterator iterator = _schemeEntities.iterator(); iterator.hasNext();) {
138 			GenericValue gv = (GenericValue) iterator.next();
139 			SchemeEntity schemeEntity = new LinkSchemeEntity(gv.getLong(SCHEME_ENTITY_ID), gv.getString(SCHEME_ENTITY_SOURCE), gv.getString(SCHEME_ENTITY_LINKTYPE), gv.getString(SCHEME_ENTITY_DESTINATION), gv.getLong(SCHEME_ENTITY_SCHEME));
140 			schemeEntities.add(schemeEntity);
141 		}
142 		return schemeEntities;
143 	}
144 
145 
146 	/**
147 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getLinkSchemeEntities(org.ofbiz.core.entity.GenericValue, java.lang.String)
148 	 */
149 	public List getLinkSchemeEntities(GenericValue scheme, String sourceIssueTypeId) throws GenericEntityException {
150 		String cacheKey = createCacheKey(scheme, sourceIssueTypeId);
151 		List result = (List) cache.get(cacheKey);
152 
153 		if (result == null) {
154 			result = scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_SOURCE, sourceIssueTypeId));
155 
156 			if (result == null)
157 				result = Collections.EMPTY_LIST;
158 
159 			if (log.isDebugEnabled())
160 				log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
161 
162 			cache.put(cacheKey, result);
163 		}
164 
165 		return result;
166 	}
167 
168 	private String createCacheKey(GenericValue scheme, String sourceIssueTypeId) {
169 		return scheme.getLong(SCHEME_ID) + "-" + sourceIssueTypeId;
170 	}
171 
172 	/**
173 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getLinkSchemeEntities(org.ofbiz.core.entity.GenericValue, java.lang.String)
174 	 */
175 	public List getLinkSchemeEntities(GenericValue scheme, String sourceIssueTypeId, String linkTypeId, String destIssueTypeId) throws GenericEntityException {
176 		String cacheKey = createCacheKey(scheme, sourceIssueTypeId, linkTypeId, destIssueTypeId);
177 		List result = (List) cache.get(cacheKey);
178 
179 		if (result == null) {
180 			result = scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_SOURCE, sourceIssueTypeId, SCHEME_ENTITY_LINKTYPE, linkTypeId, SCHEME_ENTITY_DESTINATION, destIssueTypeId));
181 			if (result == null)
182 				result = Collections.EMPTY_LIST;
183 
184 			if (log.isDebugEnabled())
185 				log.debug("Caching " + result.size() + " entities for cache key: " + cacheKey);
186 
187 			cache.put(cacheKey, result);
188 		}
189 
190 		return result;
191 	}
192 
193 	private String createCacheKey(GenericValue scheme, String sourceIssueTypeId, String linkTypeId, String destIssueTypeId) {
194 		return scheme.getLong(SCHEME_ID) + "-" + sourceIssueTypeId + "-" + linkTypeId + "-" + destIssueTypeId;
195 	}
196 
197 	/**
198 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getEntities(org.ofbiz.core.entity.GenericValue, java.lang.Long)
199 	 */
200 	public List getEntities(GenericValue scheme, String sourceTypeId) throws GenericEntityException {
201 		return getLinkSchemeEntities(scheme, sourceTypeId);
202 	}
203 
204 	/**
205 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getEntities(org.ofbiz.core.entity.GenericValue, java.lang.Long)
206 	 */
207 	public List getEntities(GenericValue scheme, Long entityTypeId) throws GenericEntityException {
208 		throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
209 	}
210 
211 	/**
212 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getEntities(org.ofbiz.core.entity.GenericValue, java.lang.Long, java.lang.String)
213 	 */
214 	public List getEntities(GenericValue scheme, Long entityTypeId, String parameter) throws GenericEntityException {
215 		throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
216 	}
217 
218 	/**
219 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getEntities(org.ofbiz.core.entity.GenericValue, java.lang.String, java.lang.Long)
220 	 */
221 	public List getEntities(GenericValue scheme, String type, Long entityTypeId) throws GenericEntityException {
222 		throw new IllegalArgumentException("Issue Type Link scheme IDs must be String values.");
223 	}
224 
225 	/**
226 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#hasSchemeAuthority(java.lang.Long, org.ofbiz.core.entity.GenericValue)
227 	 */
228 	public boolean hasSchemeAuthority(Long entityType, GenericValue entity) {
229 		return false;
230 	}
231 
232 	/**
233 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#hasSchemeAuthority(java.lang.Long, org.ofbiz.core.entity.GenericValue, com.opensymphony.user.User, boolean)
234 	 */
235 	public boolean hasSchemeAuthority(Long entityType, GenericValue entity, User user, boolean issueCreation) {
236 		return false;
237 	}
238 
239 	/**
240 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#addLinkToScheme(org.ofbiz.core.entity.GenericValue, java.lang.String, java.lang.String, java.lang.String)
241 	 */
242 	public void addLinkToScheme(GenericValue scheme, String linkTypeId, String sourceIssueTypeId, String destIssueTypeId) throws GenericEntityException {
243 		try {
244 			SchemeEntity schemeEntity = new SchemeEntity(linkTypeId, sourceIssueTypeId, destIssueTypeId);
245 
246 			// prevent adding the same combination multiple times to one scheme
247 			if (getLinkSchemeEntities(scheme, sourceIssueTypeId, linkTypeId, destIssueTypeId).size() == 0) {
248 				createSchemeEntity(scheme, schemeEntity);
249 			}
250 		} finally {
251 			clearCache();
252 		}
253 	}
254 
255 	/**
256 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#deleteIssueTypeLinkToScheme(org.ofbiz.core.entity.GenericValue, java.lang.String, java.lang.String, java.lang.String)
257 	 */
258 	public void deleteLinkToScheme(GenericValue scheme, String schemEntityId) throws GenericEntityException {
259 		try {
260 			GenericValue gvSchemeEntity = getLinkSchemeEntity(scheme, schemEntityId);
261 			if (gvSchemeEntity!=null) {
262 				gvSchemeEntity.remove();
263 			}
264 		} finally {
265 			clearCache();
266 		}
267 	}
268 	
269 	/**
270 	 * @see com.atlassian.jira.issue.link.LinkSchemeManager#getLinkSchemeEntities(org.ofbiz.core.entity.GenericValue, java.lang.String)
271 	 */
272 	public GenericValue getLinkSchemeEntity(GenericValue scheme, String schemEntityId) throws GenericEntityException {
273 		GenericValue gvSchemeEntity;
274 		gvSchemeEntity = EntityUtil.getOnly(scheme.getRelatedByAnd("Child" + getEntityName(), EasyMap.build(SCHEME_ENTITY_ID, schemEntityId)));
275 		return gvSchemeEntity;
276 	}
277 	
278 	
279 }