/*******************************************************************************
* Copyright 2005-2006, CHISEL Group, University of Victoria, Victoria, BC, Canada.
* 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
*
* Contributors:
* The Chisel Group, University of Victoria
*******************************************************************************/
package net.sourceforge.tagsea.parsed.comments;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import net.sourceforge.tagsea.core.IWaypoint;
import net.sourceforge.tagsea.parsed.parser.IParsedWaypointDescriptor;
import org.eclipse.jface.text.IRegion;
/**
* Waypoint info that also carries the region information for tags and attributes.
* @author Del Myers
*/
public class StandardCommentWaypointDescriptor implements IParsedWaypointDescriptor {
private TreeMap<String, Set<IRegion>> tagRegionMap;
private TreeMap<String, IRegion> attributeRegionMap;
private TreeMap<String, String> attributes;
private String waypointData;
private String description;
private IRegion descriptionRegion;
private int offset;
private String detail;
private int line;
public static final int UNKNOWN_CONTEXT = 0;
public static final int TAG_CONTEXT = 1;
public static final int ATTRIBUTE_CONTEXT = 2;
public static final int ATTRIBUTE_VALUE_CONTEXT = 3;
public static final int MESSAGE_CONTEXT = 4;
/**
* Creates a new waypoint descriptor that contains the given text and starts at the given
* offset in the document.
* @param text the text for the waypoint.
* @param offset the offset in the document at which the waypoint starts.
* @param line the line in the document at which the waypoint starts.
*/
StandardCommentWaypointDescriptor(String text, int offset, int line) {
this.waypointData = text;
tagRegionMap = new TreeMap<String, Set<IRegion>>();
attributeRegionMap = new TreeMap<String, IRegion>();
attributes = new TreeMap<String, String>();
this.offset = offset;
this.line = line;
}
/**
* Records the given attribute at the given location in the text (relative to the start of the
* text, not the document).
* @param key
* @param value
* @param region
*/
void putAttribute(String key, String value, IRegion region) {
attributes.put(key, value);
attributeRegionMap.put(key, region);
}
/**
* Records the given tag at the given location in the text (relative to the start of the text, not
* the document).
* @param tag
* @param region
*/
void putTag(String tag, IRegion region) {
Set<IRegion> regions = tagRegionMap.get(tag);
if (regions == null) {
regions = new HashSet<IRegion>();
tagRegionMap.put(tag, regions);
}
regions.add(region);
}
void setMessage(String description, IRegion region) {
this.description = description;
this.descriptionRegion = region;
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getAttributes()
*/
public Map<String, String> getAttributes() {
return attributes;
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getDescription()
*/
public String getMessage() {
return description;
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getTags()
*/
public String[] getTags() {
return tagRegionMap.keySet().toArray(new String[tagRegionMap.keySet().size()]);
}
/**
* Returns the text that represents the waypoint.
* @return
*/
public String getText() {
return waypointData;
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IParsedJavaWaypointInfo#getRegionsForTag(java.lang.String)
*/
public IRegion[] getRegionsForTag(String tag) {
Set<IRegion> regions = tagRegionMap.get(tag);
if (regions != null) {
return regions.toArray(new IRegion[regions.size()]);
}
return new IRegion[0];
}
/**
* Returns the region of text that represents the given attribute relative to the beginning of the
* text.
* @param key
* @return
*/
public IRegion getRegionForAttribute(String key) {
return attributeRegionMap.get(key);
}
/**
* Returns the region of text that represents the message relative to the beginning of the text.
* @return
*/
public IRegion getRegionForMessage() {
return descriptionRegion;
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IParsedJavaWaypointInfo#getOffset()
*/
public int getCharStart() {
return offset;
}
public int getCharEnd() {
return getCharStart() + getLength();
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getLength()
*/
public int getLength() {
return getText().length();
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getAuthor()
*/
public String getAuthor() {
return getAttributes().get(IWaypoint.ATTR_AUTHOR);
}
public Date getDate() {
return parseDate(getAttributes().get(IWaypoint.ATTR_DATE));
}
/* (non-Javadoc)
* @see net.sourceforge.tagsea.java.waypoints.parser.IJavaWaypointInfo#getDate()
*/
public static Date parseDate(String date) {
if (date == null) return null;
//standard way of getting the date: two characters for local, two characters for
//country, colon, short date.
int colon = date.indexOf(':');
Date result = null;
if (colon == 4) {
//interpret the locale.
String lc = date.substring(0,2);
String cn = date.substring(2,4);
date = date.substring(colon+1);
Locale locale = new Locale(lc, cn);
try {
result = DateFormat.getDateInstance(DateFormat.SHORT, locale).parse(date);
} catch (ParseException e) {
}
} else if (colon == -1) {
try {
result = DateFormat.getDateInstance(DateFormat.SHORT).parse(date);
} catch (ParseException e) {
}
}
return result;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
/**
* Returns the context at a given character index in the parsed descriptor. One of:
* {@link #UNKNOWN_CONTEXT}
* {@link #TAG_CONTEXT}
* {@link #ATTRIBUTE_CONTEXT}
* {@link #ATTRIBUTE_VALUE_CONTEXT}
* {@link #UNKNOWN_CONTEXT}
* @param index
* @return
*/
public int getContextAt(int index) {
if (descriptionRegion != null) {
if (!"".equals(description) && descriptionRegion.getOffset() <= index) {
return MESSAGE_CONTEXT;
}
}
if (index >= 0 && index <= getText().length()) {
for (String key : tagRegionMap.keySet()) {
Set<IRegion> regions = tagRegionMap.get(key);
for (IRegion region : regions) {
if (region.getOffset() <= index && index <= region.getOffset()+region.getLength()) {
return TAG_CONTEXT;
}
}
}
for (String key : attributeRegionMap.keySet()) {
IRegion region = attributeRegionMap.get(key);
if (region.getOffset() <= index && index <= region.getOffset()+region.getLength()) {
if (region.getOffset()+key.length()+2 < index) {
return ATTRIBUTE_VALUE_CONTEXT;
}
return ATTRIBUTE_CONTEXT;
}
}
}
return UNKNOWN_CONTEXT;
}
public int getLine() {
return line;
}
}