/* * Copyright 2013 Hewlett-Packard Development Company, L.P * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hp.alm.ali.idea.tasks; import com.hp.alm.ali.idea.model.Entity; import com.hp.alm.ali.idea.entity.EntityRef; import com.hp.alm.ali.idea.cfg.AliProjectConfiguration; import com.hp.alm.ali.idea.ui.editor.field.CommentField; import com.hp.alm.ali.idea.ui.editor.field.HTMLAreaField; import com.hp.alm.ali.idea.protocol.td.Handler; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.tasks.Comment; import com.intellij.tasks.Task; import com.intellij.tasks.TaskType; import javax.swing.Icon; import java.net.URL; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HpAlmTask extends Task { private static final DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); private static final Map<String, String> interfaceMap; static { interfaceMap = new HashMap<String, String>(); interfaceMap.put("defect", "IBug"); interfaceMap.put("requirement", "IRequirement"); } private static boolean openInBrowserAvailable = false; static { if(SystemInfo.isWindows && System.getProperty("ali.no.td.handler") == null) { try { URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() { public URLStreamHandler createURLStreamHandler(String proto) { if("td".equals(proto)) { return new Handler(); } else { return null; } } }); openInBrowserAvailable = true; } catch(Error e) { // cannot open browser links } } } private Project project; private Entity entity; public HpAlmTask(Project project, Entity entity) { this.project = project; this.entity = entity; } public boolean isInitialized() { return entity.isComplete() || (entity.isInitialized("name") && hasDateProperties(entity) && entity.isInitialized(getDescriptionField(entity.getType())) && (entity.isInitialized("dev-comments") || entity.isInitialized("comments"))); // comments used for requirement in ALM 12 } public String getId() { return new EntityRef(entity).toString(); } public String getSummary() { return entity.getPropertyValue("name"); } public String getDescription() { return HTMLAreaField.toPlainText(entity.getPropertyValue(getDescriptionField(entity.getType())), false); } public Comment[] getComments() { return parseComments(entity.getPropertyValue(entity.isInitialized("dev-comments")? "dev-comments": "comments")); } private Comment[] parseComments(String commentBlob) { List<Comment> list = new LinkedList<Comment>(); int last = 0; Pattern separator = Pattern.compile("<(b|strong)>________________________________________</(b|strong)>"); Matcher matcher = separator.matcher(commentBlob); while(matcher.find(last)) { list.add(HpAlmComment.parse(commentBlob.substring(last, matcher.start()))); last = matcher.end(); } if(last < commentBlob.length()) { list.add(HpAlmComment.parse(commentBlob.substring(last))); } return list.toArray(new Comment[list.size()]); } public Icon getIcon() { return null; } public TaskType getType() { if("defect".equals(entity.getType())) { return TaskType.BUG; } else { return TaskType.FEATURE; } } public Date getUpdated() { return parseDate(entity.getPropertyValue("last-modified")); } public Date getCreated() { try { Date date = CommentField.dateFormat.parse(entity.getPropertyValue("creation-time")); if("requirement".equals(entity.getType())) { return new Date(date.getTime() + timeFormat.parse(entity.getPropertyValue("req-time")).getTime() + TimeZone.getDefault().getRawOffset()); } return date; } catch(ParseException e) { return getUpdated(); } } private boolean hasDateProperties(Entity entity) { if(!entity.isInitialized("last-modified") || !entity.isInitialized("creation-time")) { return false; } if("requirement".equals(entity.getType()) && !entity.isInitialized("req-time")) { return false; } return true; } public boolean isClosed() { if("defect".equals(entity.getType())) { return "Closed".equals(entity.getPropertyValue("status")); // TODO: should be configurable } else { return false; } } // required in 11.0 public String getCustomIcon() { return null; } public boolean isIssue() { return getType() == TaskType.BUG; } public String getIssueUrl() { if(openInBrowserAvailable) { return _getIssueUrl(); } else { return null; } } String _getIssueUrl() { AliProjectConfiguration conf = project.getComponent(AliProjectConfiguration.class); StringBuffer url = new StringBuffer(); url.append("td://"); url.append(conf.getProject()); url.append("."); url.append(conf.getDomain()); url.append("."); url.append(conf.getLocation().replaceFirst("^[Hh][Tt][Tt][Pp][Ss]?://", "")); url.append("/[AnyModule]?EntityType="); url.append(interfaceMap.get(entity.getType())); url.append("&EntityID="); url.append(entity.getId()); url.append("&ShowDetails=Y"); return url.toString(); } public static Date parseDate(String dateStr) { try { return dateTimeFormat.parse(dateStr); } catch (ParseException e) { return new Date(); } } public static String getDescriptionField(String entityType) { if("defect".equals(entityType)) { return "description"; } else { return "req-comment"; } } }