001: package com.technoetic.xplanner.tags;
002:
003: import java.net.MalformedURLException;
004: import java.util.ArrayList;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.List;
008: import java.util.Map;
009: import javax.servlet.http.HttpServletRequest;
010: import javax.servlet.jsp.JspException;
011: import javax.servlet.jsp.tagext.TagSupport;
012:
013: import net.sf.hibernate.HibernateException;
014: import net.sf.hibernate.Session;
015: import org.apache.log4j.Logger;
016: import org.apache.struts.util.RequestUtils;
017: import org.apache.struts.util.ResponseUtils;
018:
019: import com.technoetic.xplanner.db.hibernate.ThreadSession;
020: import com.technoetic.xplanner.domain.Feature;
021: import com.technoetic.xplanner.domain.Iteration;
022: import com.technoetic.xplanner.domain.Project;
023: import com.technoetic.xplanner.domain.Task;
024: import com.technoetic.xplanner.domain.UserStory;
025: import com.technoetic.xplanner.security.AuthenticationException;
026: import com.technoetic.xplanner.security.SecurityHelper;
027: import com.technoetic.xplanner.security.auth.SystemAuthorizer;
028:
029: public class OutlineTag extends TagSupport {
030: private Logger log = Logger.getLogger(getClass());
031: private final String br = "<br>";
032: public static final String PREVIOUS = "<<";
033: public static final String NEXT = ">>";
034:
035: public int doStartTag() throws JspException {
036: DomainContext context = DomainContext.get(pageContext
037: .getRequest());
038: if (context != null) {
039: doOutline(context);
040: }
041: return EVAL_BODY_INCLUDE;
042: }
043:
044: private void doOutline(DomainContext context) throws JspException {
045: String spacer = getImageUrl("spacer.gif");
046: String elbow = getImageUrl("elbow.gif");
047: String[] names = { context.getProjectName(),
048: context.getIterationName(), context.getStoryName(),
049: context.getTaskName(), context.getFeatureName() };
050:
051: String[] objects = { "project", "iteration", "userstory",
052: "task", "feature" };
053: int[] ids = { context.getProjectId(), context.getIterationId(),
054: context.getStoryId(), context.getTaskId(),
055: context.getFeatureId() };
056: StringBuffer buffer = new StringBuffer();
057: int indent = 0;
058:
059: buffer.append("<div class='navigation_outline'>\n");
060: for (int i = 0; i < names.length; i++) {
061: String name = names[i];
062: if (name != null) {
063: for (int j = 0; j < (indent * 3); j++) {
064: buffer.append(spacer);
065: }
066: buffer.append(elbow);
067: int[] nextPrevIds = getNextPrevId(ids, objects[i]);
068: if (ids[i] != nextPrevIds[0]) {
069: buffer.append(renderLink(PREVIOUS, nextPrevIds[0],
070: objects[i], context));
071: buffer.append(" ");
072: }
073: if (i == names.length - 1
074: || (names[i + 1] == null && (i == names.length - 2 || names[i + 2] == null))) {
075: buffer.append(name);
076: } else {
077: buffer.append(renderLink(name, ids[i], objects[i],
078: context));
079: }
080: if (ids[i] != nextPrevIds[1]) {
081: buffer.append(" ");
082: buffer.append(renderLink(NEXT, nextPrevIds[1],
083: objects[i], context));
084: }
085: buffer.append(br);
086: indent++;
087: }
088: }
089: buffer.append("</div>\n");
090: ResponseUtils.write(pageContext, buffer.toString());
091: }
092:
093: private int[] getNextPrevId(int[] ids, String type)
094: throws JspException {
095: Session session = ThreadSession.get();
096: try {
097: //DEBT remove this magic strings.
098: if ("project".equals(type)) {
099: Project project = (Project) session.load(Project.class,
100: new Integer(ids[0]));
101: List list = session.find("from project in "
102: + Project.class + " order by project.name asc");
103:
104: list = verifyProjectAccess(list);
105:
106: int[] nextPrevIndexes = calculateIndex(list
107: .indexOf(project), list.size());
108: int[] nextPrevIds = {
109: ((Project) list.get(nextPrevIndexes[0]))
110: .getId(),
111: ((Project) list.get(nextPrevIndexes[1]))
112: .getId() };
113: return nextPrevIds;
114: }
115: if ("iteration".equals(type)) {
116: Iteration iteration = (Iteration) session.load(
117: Iteration.class, new Integer(ids[1]));
118: List list = session.find("from iteration in "
119: + Iteration.class + " where project_id="
120: + ids[0] + " order by iteration.startDate asc");
121: int[] nextPrevIndexes = calculateIndex(list
122: .indexOf(iteration), list.size());
123: int[] nextPrevIds = {
124: ((Iteration) list.get(nextPrevIndexes[0]))
125: .getId(),
126: ((Iteration) list.get(nextPrevIndexes[1]))
127: .getId() };
128: return nextPrevIds;
129: }
130: if ("userstory".equals(type)) {
131: UserStory userstory = (UserStory) session.load(
132: UserStory.class, new Integer(ids[2]));
133: List list = session.find("from story in "
134: + UserStory.class + " where iteration_id="
135: + ids[1] + " order by story.orderNo asc");
136: int[] nextPrevIndexes = calculateIndex(list
137: .indexOf(userstory), list.size());
138: int[] nextPrevIds = {
139: ((UserStory) list.get(nextPrevIndexes[0]))
140: .getId(),
141: ((UserStory) list.get(nextPrevIndexes[1]))
142: .getId() };
143: return nextPrevIds;
144: }
145: if ("task".equals(type)) {
146: Task task = (Task) session.load(Task.class,
147: new Integer(ids[3]));
148: List list = session.find("from task in " + Task.class
149: + " where story_id=" + ids[2]
150: + " order by task.name asc");
151: int[] nextPrevIndexes = calculateIndex(list
152: .indexOf(task), list.size());
153: int[] nextPrevIds = {
154: ((Task) list.get(nextPrevIndexes[0])).getId(),
155: ((Task) list.get(nextPrevIndexes[1])).getId() };
156: return nextPrevIds;
157: }
158: if ("feature".equals(type)) {
159: Feature feature = (Feature) session.load(Feature.class,
160: new Integer(ids[4]));
161: List list = session.find("from feature in "
162: + Feature.class + " where story_id=" + ids[2]
163: + " order by feature.name asc");
164: int[] nextPrevIndexes = calculateIndex(list
165: .indexOf(feature), list.size());
166: int[] nextPrevIds = {
167: ((Feature) list.get(nextPrevIndexes[0]))
168: .getId(),
169: ((Feature) list.get(nextPrevIndexes[1]))
170: .getId() };
171: return nextPrevIds;
172: }
173: } catch (HibernateException e) {
174: log.error("error", e);
175: }
176:
177: return null;
178: }
179:
180: private List verifyProjectAccess(List list) throws JspException {
181: Iterator iterator = list.iterator();
182: ArrayList newList = new ArrayList();
183: while (iterator.hasNext()) {
184: Project project = (Project) iterator.next();
185: boolean hasPermission = false;
186: try {
187: hasPermission = SystemAuthorizer.get().hasPermission(
188: project.getId(),
189: SecurityHelper.getRemoteUserId(pageContext),
190: project, "read");
191: } catch (AuthenticationException e) {
192: throw new JspException(e.getMessage());
193: }
194: if (hasPermission) {
195: newList.add(project);
196: }
197: }
198: return newList;
199: }
200:
201: private int[] calculateIndex(int index, int listSize) {
202: int[] indexes = { 0, 0 };
203: if (index > 0) {
204: indexes[0] = index - 1;
205: } else {
206: indexes[0] = index;
207: }
208: if (index < listSize - 1) {
209: indexes[1] = index + 1;
210: } else {
211: indexes[1] = index;
212: }
213: return indexes;
214: }
215:
216: private StringBuffer renderLink(String name, int id, String type,
217: DomainContext context) {
218: try {
219:
220: StringBuffer buffer = null;
221: if (!name.equals(PREVIOUS) && !name.equals(NEXT)) {
222: buffer = new StringBuffer("<a href='");
223: } else {
224: if (name.equals(PREVIOUS)) {
225: buffer = new StringBuffer("<a id="
226: + type.substring(0, 1) + "_desc href='");
227: } else {
228: buffer = new StringBuffer("<a id="
229: + type.substring(0, 1) + "_asc href='");
230: }
231: }
232: HashMap params = new HashMap();
233: params.put("oid", new Integer(id));
234:
235: //params.put("returnto","/do/view/"+type+"?oid="+id);
236: //params.put("fkey",""+id);
237:
238: //buffer.append(RequestUtils.computeURL(pageContext, null, null, "/do/view/" + type,
239: // null, params, null, false));
240:
241: String url = null;
242:
243: if (context.getActionMapping() != null) {
244: url = getUrl(context.getActionMapping().getPath(),
245: type, params);
246: } else {
247: url = RequestUtils.computeURL(pageContext, null, null,
248: "/do/view/" + type, null, params, null, false);
249: }
250:
251: buffer.append(url);
252: buffer.append("'>");
253: if (PREVIOUS.equals(name)) {
254: name = getImageUrl("previous.gif");
255: } else if (NEXT.equals(name)) {
256: name = getImageUrl("next.gif");
257: }
258: buffer.append(name);
259: buffer.append("</a>");
260: return buffer;
261: } catch (MalformedURLException e) {
262: log.error("error", e);
263: return new StringBuffer("");
264: }
265: }
266:
267: private String getUrl(String path, String type, Map params)
268: throws MalformedURLException {
269: String url = null;
270: url = RequestUtils.computeURL(pageContext, null, null, "/do"
271: + path, null, params, null, false);
272: if ("project".equals(type) && path.endsWith("history")) {
273: //url = url+"&oid="+id+"&@type="+(new Project()).getClass().getName()+"&container=true";
274: url = url + "&@type="
275: + (new Project()).getClass().getName()
276: + "&container=true";
277: } else if ("iteration".equals(type)
278: && (path.endsWith("metrics")
279: || path.endsWith("statistics")
280: || path.endsWith("accuracy")
281: || path.endsWith("history") || path
282: .endsWith("tasks"))) {
283: //url = url+"&oid="+id+"&@type="+(new Iteration()).getClass().getName()+"&container=true";
284: url = url + "&@type="
285: + (new Iteration()).getClass().getName()
286: + "&container=true";
287: } else if ("userstory".equals(type) && path.endsWith("history")) {
288: //url = url+"&oid="+id+"&@type="+(new UserStory()).getClass().getName()+"&container=true";
289: url = url + "&@type="
290: + (new UserStory()).getClass().getName()
291: + "&container=true";
292: } else if ("task".equals(type) && path.endsWith("history")) {
293: //url = url+"&oid="+id+"&@type="+(new Task()).getClass().getName()+"&container=true";
294: url = url + "&@type="
295: + (new Task()).getClass().getName()
296: + "&container=true";
297: } else {
298: url = RequestUtils.computeURL(pageContext, null, null,
299: "/do/view/" + type, null, params, null, false);
300: }
301: return url;
302: }
303:
304: private String getImageUrl(String imageFileName) {
305: return "<img src=\"" + getContextPath() + "/images/"
306: + imageFileName + "\">";
307: }
308:
309: private String getContextPath() {
310: return ((HttpServletRequest) pageContext.getRequest())
311: .getContextPath();
312: }
313:
314: public void release() {
315: super.release();
316: }
317: }
|