# Insert tags around entities in body

Because we're passing object to Spring Framework in which Jackson classes convert them into JSON as a response, we chose to implement a simpler Tweet class rather than the Twitter4j-provided Status class, which includes numerous data that is irrelevant.

Status class provided by Twitter4j has arrays of entities that specify start and end indices of the entity in the body text.

For example:

Hello @fuxximus, how are you?

The tweet will have an entity @fuxximus with indices: start 6 end 15. So having multiple entities and inserting tags around them makes any index after the inserted shifted by the number of chars of the inserted tag/string. I don't think the entities are sorted in the order of their appearance, and even so it wouldn't matter because there are different types of entities.

So to account to that I came up with a simple HashMap that registers all indices and their added string length as they're entered, then when inserting every next insertion it calculates its new offset if change to it has been made from the HashMap.

Note: the tags will be more dynamic in the future, so the length of the tag will be variable.

Is there a more elegant way of solving this than using HashMap and looping through it every single entity? I couldn't come up with anything else.

package com.univision.proxy.data.twitter;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Tweet {
public String name;
public String screenname;
public Date time;
public String body;
public Boolean is_retweet = false;
public String original_name = null;
public String original_screenname = null;
public Date original_time = null;
public long original_id = 0;
public long id;
public Tweet(Status stat){
if(stat.isRetweet()){
this.is_retweet = true;
this.original_name = stat.getUser().getName();
this.original_screenname = stat.getUser().getScreenName();
this.original_time = stat.getCreatedAt();
this.original_id = stat.getId();
stat = stat.getRetweetedStatus();
}
this.name = stat.getUser().getName();
this.screenname = stat.getUser().getScreenName();
this.time = stat.getCreatedAt();
this.id = stat.getId();

this.body = ParseTweetText(stat);
}

public static String ParseTweetText(Status stat)    {
StringBuffer body = new StringBuffer(stat.getText());

HashtagEntity[] hashtags = stat.getHashtagEntities();
MediaEntity[] medias = stat.getMediaEntities();
URLEntity[] urls = stat.getURLEntities();
UserMentionEntity[] users = stat.getUserMentionEntities();

String tag = "";
for(HashtagEntity hashtag : hashtags){
tag = "</span>";
}
for(MediaEntity media : medias){
tag = "</span>";
}
for(URLEntity url : urls){
tag = "</span>";
}
for(UserMentionEntity user : users){
tag = "</span>";
}

return body.toString();
}

public static int CalculateOffset(HashMap<Integer,Integer> indices, int index)  {
int ret_val = index;
for (Map.Entry<Integer, Integer> entry : indices.entrySet()) {
if(index > entry.getKey()){
ret_val += entry.getValue();
}
}
return ret_val;
}
}


If the interfaces HashtagEntity, MediaEntity, URLEntity, and UserMentionEntity were subinterfaces of a superinterface Entity, you could refactor the 4 loops into 4 calls to one function that would take Entity[] as one of the parameters, although with the Java inability to pass byref, I'm not sure it would be that good.
• Yes, that's why I said "If". It looks like you are already messing with the source code by replacing the provided Tweet class with your own. You can create the Entity interface yourself and make the other interface become subinterfaces of the Entity one. – Michael Pereira Mar 15 '13 at 15:52