package com.akjava.gwt.markdowneditor.client; import java.util.Collections; import java.util.List; import java.util.Map; import com.akjava.lib.common.predicates.StringPredicates; import com.akjava.lib.common.utils.CSVUtils; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Splitter; import com.google.common.base.Strings; import com.google.common.collect.FluentIterable; import com.google.common.collect.Lists; public class KeyAndUrlUtils { private KeyAndUrlUtils(){} public static List<KeyAndUrl> loadFromCsvText(String text){ List<KeyAndUrl> lists=FluentIterable.from(CSVUtils.splitLinesWithGuava(text)) .filter(StringPredicates.getNotEmpty()) .transform(getTextToKeyAndUrlFunction()).toList(); return Lists.newArrayList(lists);//for sort } public static TextToKeyAndUrlFunction getTextToKeyAndUrlFunction(){ return TextToKeyAndUrlFunction.INSTANCE; } public enum TextToKeyAndUrlFunction implements Function<String,KeyAndUrl>{ INSTANCE; private Splitter splitter=Splitter.on(",").limit(3);//now support icon @Override public KeyAndUrl apply(String input) { List<String> values=Lists.newArrayList(splitter.split(input)); String key=values.get(0);//must be String url=values.size()>1?values.get(1):"#"; String icon=values.size()>2?values.get(2):null; return new KeyAndUrl(key,url,icon); } } /** * same path should not replaced,but need exist otherwise other key replace it. * so set setReplaceWithoutLink(false) to avoid exec final replace * @author aki * */ public static class SamePageReplaceWithoutLinkFunction implements Function<KeyAndUrl,KeyAndUrl>{ private String targetPath; public SamePageReplaceWithoutLinkFunction(String targetPath) { super(); this.targetPath = targetPath; } @Override public KeyAndUrl apply(KeyAndUrl input) { if(input.getUrl().equals(targetPath)){ input.setReplaceWithoutLink(true); }else{ input.setReplaceWithoutLink(false); } return input; } } public static final boolean EachKeyOnlyOnce=true; /** * this function do sort * @param extractedValues * @param keywords * @param eachKeyOnlyOnce */ public static void insertKeyAndUrl(Map<String,String> extractedValues,List<KeyAndUrl> keywords,boolean eachKeyOnlyOnce){ //reset used for(KeyAndUrl key:keywords){ if(key.isUsed()){ key.setUsed(false); } } //use keywords directory to cut down time. Collections.sort(keywords); for(String keyName:extractedValues.keySet()){ String value=extractedValues.get(keyName); String newValue=replaceTextToKeyAndUrl(value,keywords,eachKeyOnlyOnce); extractedValues.put(keyName, newValue); } } public static String createIconLink(String icon){ if(Strings.isNullOrEmpty(icon)){ return ""; }else{ return "<i class=\""+icon+"\"></i>"; } } /** * this is totally replace,do extract first * and sort before by yourself ,usually called insertKeyAndUrl so not sort * Collections.sort(keywords); * * @param text * @param keywords must be sorted * @return */ public static String replaceTextToKeyAndUrl(String text,List<KeyAndUrl> keywords,boolean eachKeyOnlyOnce){ StringBuilder sbuilder=new StringBuilder(); String remainText=text; String notMatchText=""; while(remainText.length()>0){ boolean match=false; FOR:for(int j=0;j<keywords.size();j++){ KeyAndUrl keyword=keywords.get(j); if(remainText.startsWith(keyword.getKey())){ //System.out.println("mutch:"+keyword); if(notMatchText.length()>0){ sbuilder.append(notMatchText); } if((eachKeyOnlyOnce && keyword.isUsed())||keyword.isReplaceWithoutLink() ){ sbuilder.append(keyword.getKey());//add as plain }else{ if(keyword.getUrl().isEmpty()){ sbuilder.append(MarkdownUtils.createItalic(keyword.getKey())); keyword.setUsed(true); }else{ sbuilder.append(createIconLink(keyword.getIcon())+MarkdownUtils.createLink(keyword.getKey(), keyword.getUrl())); keyword.setUsed(true); } } notMatchText=""; remainText=remainText.substring(keyword.getKey().length()); match=true; break FOR; } } //check each character if(match==false){ notMatchText+=remainText.charAt(0); remainText=remainText.substring(1); } } //finally add remain. if(notMatchText.length()>0){ sbuilder.append(notMatchText); } return sbuilder.toString(); } }