Skip to main content
summaryrefslogblamecommitdiffstats
blob: 0a8dccf1a37a26e4682be867b3506a393e53a574 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                                



                                                                        

                                                                                 
                                                 
 
                           
                         
                      


                        
                                                      





                                                              










                                                                     

                                                            





                                                                                             
                                                                                                            


                                   
                                                
 
                                                        
 
                                            
 

                                            

                                           

                                                             

                                                  


                                             
 

                                                  

                                                                                                       
                                               
                                                 
                                           









                                            


                                                                                      
                                                                            




                                                                                                                         
                                                                  


                                                                                    
                     
                                                                                                      














                                                                                           
                                                                                     

                                           
                                                                 

                               
                                                                    
                              




                                                                                          
                                                                              







                                                                                  
                                                                                                                                    
                                                                        


                                 








                                                                                                                                      



                                                                                  
                                                                                                                                       
                                                                        


                                 
                                
                                                 

                                                                                                                       








                                                                                                
                                                          
 
                                                                                    

                                                                                                          





                                                                                              


                                                                                                            
                                
                                                                  


                         
                                                                  
                     
                                                                                                      











                                                                                        
                                                                                     




                                                                                                
                                                                                                           
                                           
                                                                                                        

                                                  
 


                              
                                             
                         
                                                  
                                                                

                              

                                                  
                                                                          



                                                  
                                                                     



                                                  
                                                           


                              
                                        
                              
                                                                                           
                                                                                      
                                                                                          
                                                           
                                                               


                                                               
                          

                                 
                          


                                                                      
                              
                              


                                                                   
                              

                           


                                                                      
                              
                          
                                                 






                                                                                                 

                              
                                


                                                                        


                                             
                                                   
                              


                                  
                              
                                  

                              
                                              
 
                                                    
 
                                                                                               
                                                                                                             
                                                                                   
                                                           
                                                                                                                  
                                                                                  

                         


                                                                       





                                                                                               
                              
                             
                                                         
                               


                                                                                                                      
                                

                                                                            
                                        
                                                                                                               


                                 

                                
                              
                        



                                                                                                                       
                                
                                                                      

                              



                 
                                                 
                                                                                                                  



























































                                                                                                                             
                                                         
                                                                                                           
                                                             
                                                      

         


                                                                                       
                                                                                        
                                                          
                                                  



                                                                                                                    
                                                                                                             

                                                                                                                 




                                                                               
                                               
                             


                                             

         
                                                    
                                                                 

                                         
                                                       




                                                                                                                   
                                                                                     



                                 
 
                                          



















                                               
 
/*******************************************************************************
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipse.mylyn.internal.bugzilla.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.core.data.TaskCommentMapper;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Parser for xml bugzilla reports.
 * 
 * @author Rob Elves
 */
public class SaxMultiBugReportContentHandler extends DefaultHandler {

	private static final String ATTRIBUTE_NAME = "name";

	private static final String COMMENT_ATTACHMENT_STRING = "Created an attachment (id=";

	private StringBuffer characters;

	private TaskComment taskComment;

	private Map<String, TaskCommentMapper> attachIdToComment = new HashMap<String, TaskCommentMapper>();

	private int commentNum = 0;

	private TaskAttachmentMapper attachment;

	private final Map<String, TaskData> taskDataMap;

	private TaskData repositoryTaskData;

	private List<TaskComment> longDescs;

	private String errorMessage = null;

	private final List<BugzillaCustomField> customFields;

	private final TaskDataCollector collector;

	private boolean isDeprecated = false;

	private boolean isPatch = false;

	private TaskAttribute attachmentAttribute;

	public SaxMultiBugReportContentHandler(TaskAttributeMapper mapper, TaskDataCollector collector,
			Map<String, TaskData> taskDataMap, List<BugzillaCustomField> customFields) {
		this.taskDataMap = taskDataMap;
		this.customFields = customFields;
		this.collector = collector;
	}

	public boolean errorOccurred() {
		return errorMessage != null;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		characters.append(ch, start, length);
		//System.err.println(String.copyValueOf(ch, start, length));
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		characters = new StringBuffer();
		BugzillaAttribute tag = BugzillaAttribute.UNKNOWN;
		if (localName.startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
			return;
		}
		try {
			tag = BugzillaAttribute.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
		} catch (RuntimeException e) {
			if (e instanceof IllegalArgumentException) {
				// ignore unrecognized tags
				return;
			}
			throw e;
		}
		switch (tag) {
		case BUGZILLA:
			// Note: here we can get the bugzilla version if necessary
			break;
		case BUG:
			if (attributes != null && (attributes.getValue("error") != null)) {
				errorMessage = attributes.getValue("error");
			}
			attachIdToComment = new HashMap<String, TaskCommentMapper>();
			commentNum = 0;
			taskComment = null;
			longDescs = new ArrayList<TaskComment>();
			break;
		case LONG_DESC:
			taskComment = new TaskComment(commentNum++);
			break;
		case WHO:
			if (taskComment != null) {
				if (attributes != null && attributes.getLength() > 0) {
					String name = attributes.getValue(ATTRIBUTE_NAME);
					if (name != null) {
						taskComment.authorName = name;
					}
				}
			}
			break;
		case REPORTER:
			if (attributes != null && attributes.getLength() > 0) {
				String name = attributes.getValue(ATTRIBUTE_NAME);
				if (name != null) {
					BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.REPORTER_NAME)
							.setValue(name);
				}
			}
			break;
		case QA_CONTACT:
			if (attributes != null && attributes.getLength() > 0) {
				String name = attributes.getValue(ATTRIBUTE_NAME);
				if (name != null) {
					BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.QA_CONTACT_NAME)
							.setValue(name);
				}
			}
			break;
		case ASSIGNED_TO:
			if (attributes != null && attributes.getLength() > 0) {
				String name = attributes.getValue(ATTRIBUTE_NAME);
				if (name != null) {
					BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.ASSIGNED_TO_NAME)
							.setValue(name);
				}
			}
			break;
		case ATTACHMENT:
			if (attributes != null) {
				isDeprecated = "1".equals(attributes.getValue(BugzillaAttribute.IS_OBSOLETE.getKey()));
				isPatch = "1".equals(attributes.getValue(BugzillaAttribute.IS_PATCH.getKey()));
			}
			break;
		}

	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {

		String parsedText = characters.toString();

		if (localName.startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
			TaskAttribute endAttribute = repositoryTaskData.getRoot().getAttribute(localName);
			if (endAttribute == null) {
				String desc = "???";
				for (BugzillaCustomField bugzillaCustomField : customFields) {
					if (localName.equals(bugzillaCustomField.getName())) {
						desc = bugzillaCustomField.getDescription();
					}
				}
				TaskAttribute atr = repositoryTaskData.getRoot().createAttribute(localName);
				atr.getMetaData().defaults().setLabel(desc).setReadOnly(true);
				atr.setValue(parsedText);
			} else {
				endAttribute.addValue(parsedText);
			}
		}

		BugzillaAttribute tag = BugzillaAttribute.UNKNOWN;
		try {
			tag = BugzillaAttribute.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
		} catch (RuntimeException e) {
			if (e instanceof IllegalArgumentException) {
				// ignore unrecognized tags
				return;
			}
			throw e;
		}
		switch (tag) {
		case BUG_ID: {
			try {
				repositoryTaskData = taskDataMap.get(parsedText.trim());
				if (repositoryTaskData == null) {
					errorMessage = parsedText + " id not found.";
				}
			} catch (Exception e) {
				errorMessage = "Bug id from server did not match requested id.";
			}

			TaskAttribute attr = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
			if (attr == null) {
				attr = BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag);
			}
			attr.setValue(parsedText);

			break;
		}

			// Comment attributes
		case WHO:
			if (taskComment != null) {
				taskComment.author = parsedText;
			}
			break;
		case BUG_WHEN:
			if (taskComment != null) {
				taskComment.createdTimeStamp = parsedText;
			}
			break;
		case THETEXT:
			if (taskComment != null) {
				taskComment.commentText = parsedText;
			}
			break;
		case LONG_DESC:
			if (taskComment != null) {
				longDescs.add(taskComment);
			}
			break;

		// Attachment attributes
		case ATTACHID:
			attachmentAttribute = repositoryTaskData.getRoot().createAttribute(
					TaskAttribute.PREFIX_ATTACHMENT + parsedText);
			attachment = TaskAttachmentMapper.createFrom(attachmentAttribute);
			attachment.setLength(new Long(-1));
			attachment.setAttachmentId(parsedText);
			attachment.setPatch(isPatch);
			attachment.setDeprecated(isDeprecated);
			break;
		case DATE:
			// ignore
			break;
		case DESC:
			if (attachment != null) {
				attachment.setDescription(parsedText);
			}
			break;
		case FILENAME:
			if (attachment != null) {
				attachment.setFileName(parsedText);
			}
			break;
		case CTYPE:
		case TYPE:
			if (attachment != null) {
				attachment.setContentType(parsedText);
			}
			break;
		case SIZE:
			if (attachment != null) {
				try {
					if (parsedText != null) {
						attachment.setLength(Long.parseLong(parsedText));
					}
				} catch (NumberFormatException e) {
					// ignore
				}
			}
			break;
		case ATTACHMENT:
			if (attachment != null) {
				attachment.applyTo(attachmentAttribute);
			}
			isPatch = false;
			isDeprecated = false;
			attachment = null;
			attachmentAttribute = null;
			break;
		case DATA:
			// ignored
			break;
		case BUGZILLA:
			// ignored
			break;
		case BUG:
			// Reached end of bug.

			addDescriptionAndComments();

			// Need to set LONGDESCLENGTH to number of comments + 1 for description
			TaskAttribute numCommentsAttribute = repositoryTaskData.getRoot().getMappedAttribute(
					BugzillaAttribute.LONGDESCLENGTH.getKey());
			if (numCommentsAttribute == null) {
				numCommentsAttribute = BugzillaTaskDataHandler.createAttribute(repositoryTaskData,
						BugzillaAttribute.LONGDESCLENGTH);
			}

			numCommentsAttribute.setValue("" + commentNum);

			updateAttachmentMetaData();
			TaskAttribute attrCreation = repositoryTaskData.getRoot().getAttribute(
					BugzillaAttribute.CREATION_TS.getKey());
			// Guard against empty data sets
			if (attrCreation != null && !attrCreation.equals("")) {
				collector.accept(repositoryTaskData);
			}
			break;
		case BLOCKED:
			// handled similarly to DEPENDSON
		case DEPENDSON:
			TaskAttribute blockOrDepends = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
			if (blockOrDepends == null) {
				BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag).setValue(parsedText);
			} else {
				if (blockOrDepends.getValue().equals("")) {
					blockOrDepends.setValue(parsedText);
				} else {
					blockOrDepends.setValue(blockOrDepends.getValue() + ", " + parsedText);
				}
			}
			break;
		case UNKNOWN:
			//ignore
			break;
		default:
			TaskAttribute defaultAttribute = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
			if (defaultAttribute == null) {
				defaultAttribute = BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag);
				defaultAttribute.setValue(parsedText);
			} else {
				defaultAttribute.addValue(parsedText);
			}
			break;
		}

	}

	private void updateAttachmentMetaData() {
		List<TaskAttribute> taskAttachments = repositoryTaskData.getAttributeMapper().getAttributesByType(
				repositoryTaskData, TaskAttribute.TYPE_ATTACHMENT);
		for (TaskAttribute attachment : taskAttachments) {
			TaskAttachmentMapper attachmentMapper = TaskAttachmentMapper.createFrom(attachment);
			TaskCommentMapper taskComment = attachIdToComment.get(attachmentMapper.getAttachmentId());
			if (taskComment != null) {
				attachmentMapper.setAuthor(taskComment.getAuthor());
				attachmentMapper.setCreationDate(taskComment.getCreationDate());
			}
			attachmentMapper.setUrl(repositoryTaskData.getRepositoryUrl()
					+ IBugzillaConstants.URL_GET_ATTACHMENT_SUFFIX + attachmentMapper.getAttachmentId());
			attachmentMapper.applyTo(attachment);
		}
	}

	private void addDescriptionAndComments() {
		int longDescsSize = longDescs.size() - 1;
		commentNum = 1;
		if (longDescsSize == 0) {
			addDescription(longDescs.get(0).commentText);
		} else if (longDescsSize == 1) {
			if (longDescs.get(0).createdTimeStamp.compareTo(longDescs.get(1).createdTimeStamp) <= 0) {
				// if created_0 is equal to created_1 we assume that longDescs at index 0 is the description.
				addDescription(longDescs.get(0).commentText);
				addComment(longDescs.get(1));
			} else {
				addDescription(longDescs.get(1).commentText);
				addComment(longDescs.get(0));
			}
		} else if (longDescsSize > 1) {
			String created_0 = longDescs.get(0).createdTimeStamp;
			String created_1 = longDescs.get(1).createdTimeStamp;
			String created_n = longDescs.get(longDescsSize).createdTimeStamp;
			if (created_0.compareTo(created_1) <= 0 && created_0.compareTo(created_n) < 0) {
				// if created_0 is equal to created_1 we assume that longDescs at index 0 is the description.
				addDescription(longDescs.get(0).commentText);

				if (created_1.compareTo(created_n) < 0) {
					for (int i = 1; i <= longDescsSize; i++) {
						addComment(longDescs.get(i));
					}
				} else {
					for (int i = longDescsSize; i > 0; i--) {
						addComment(longDescs.get(i));
					}
				}
			} else {
				addDescription(longDescs.get(longDescsSize).commentText);
				if (created_0.compareTo(created_1) < 0) {
					for (int i = 0; i < longDescsSize; i++) {
						addComment(longDescs.get(i));
					}
				} else {
					for (int i = longDescsSize - 1; i >= 0; i--) {
						addComment(longDescs.get(i));
					}
				}
			}
		}
	}

	private void addDescription(String commentText) {
		TaskAttribute attrDescription = BugzillaTaskDataHandler.createAttribute(repositoryTaskData,
				BugzillaAttribute.LONG_DESC);
		attrDescription.setValue(commentText);
	}

	private void addComment(TaskComment comment) {
		TaskAttribute attribute = repositoryTaskData.getRoot().createAttribute(
				TaskAttribute.PREFIX_COMMENT + commentNum);
		TaskCommentMapper taskComment = TaskCommentMapper.createFrom(attribute);
		taskComment.setCommentId(commentNum + "");
		taskComment.setNumber(commentNum);
		IRepositoryPerson author = repositoryTaskData.getAttributeMapper().getTaskRepository().createPerson(
				comment.author);
		author.setName(comment.authorName);
		taskComment.setAuthor(author);
		TaskAttribute attrTimestamp = attribute.createAttribute(BugzillaAttribute.BUG_WHEN.getKey());
		attrTimestamp.setValue(comment.createdTimeStamp);
		taskComment.setCreationDate(repositoryTaskData.getAttributeMapper().getDateValue(attrTimestamp));
		if (comment.commentText != null) {
			String commentText = comment.commentText.trim() + "\n";
			taskComment.setText(commentText);

		}
		taskComment.applyTo(attribute);
		commentNum++;

		parseAttachment(taskComment);

	}

	/** determines attachment id from comment */
	private void parseAttachment(TaskCommentMapper comment) {

		String attachmentID = "";
		String commentText = comment.getText();
		if (commentText.startsWith(COMMENT_ATTACHMENT_STRING)) {
			int endIndex = commentText.indexOf(")");
			if (endIndex > 0 && endIndex < commentText.length()) {
				attachmentID = commentText.substring(COMMENT_ATTACHMENT_STRING.length(), endIndex);
				if (!attachmentID.equals("")) {
					attachIdToComment.put(attachmentID, comment);
				}
			}
		}
	}

	private static class TaskComment {

		public int number;

		public String author;

		public String authorName;

		public String createdTimeStamp;

		public String commentText;

		public boolean hasAttachment;

		public String attachmentId;

		public TaskComment(int num) {
			this.number = num;
		}
	}

}

Back to the top