001    /**
002     * Implements the Cold Fusion Function refind
003     */
004    package railo.runtime.functions.string;
005    
006    import railo.commons.io.SystemUtil;
007    import railo.runtime.PageContext;
008    import railo.runtime.exp.ExpressionException;
009    import railo.runtime.exp.FunctionException;
010    import railo.runtime.ext.function.Function;
011    import railo.runtime.op.Caster;
012    import railo.runtime.type.Array;
013    import railo.runtime.type.List;
014    
015    public final class Wrap implements Function {
016            public static String call(PageContext pc , String string, double limit) throws ExpressionException {
017                    return call(pc,string,limit,false);
018            }
019            public static String call(PageContext pc , String string, double limit, boolean strip) throws ExpressionException {
020                    if(strip) {
021                        string=REReplace.call(pc,string,"[[:space:]]"," ","all");
022                    }
023                int _limit=(int) limit;
024                if(limit<1) throw new FunctionException(pc,"Wrap",2,"limit","value mus be a positive number");
025                return wrap(string,_limit);
026            }
027            
028    
029            /**
030             * wraps a String to specified length
031             * @param str string to erap
032             * @param wrapTextLength
033             * @return wraped String
034             */
035            public static String wrap(String str, int wrapTextLength) {
036                    if(wrapTextLength<=0)return str;
037                    
038                    StringBuffer rtn=new StringBuffer();
039                    String ls=SystemUtil.getOSSpecificLineSeparator();
040                    Array arr = List.listToArray(str,ls);
041                    int len=arr.size();
042                    
043                    for(int i=1;i<=len;i++) {
044                            rtn.append(wrapLine(Caster.toString(arr.get(i,""),""),wrapTextLength));
045                            if(i+1<len)rtn.append(ls);
046                    }
047                    return rtn.toString();
048            }
049    
050            /**
051             * wrap a single line
052             * @param str
053             * @param wrapTextLength
054             * @return
055             */
056            private static String wrapLine(String str, int wrapTextLength) {
057                    int wtl=wrapTextLength;
058                    
059                    if(str.length()<=wtl) return str;
060                    
061                    String sub=str.substring(0,wtl);
062                    String rest=str.substring(wtl);
063                    char firstR=rest.charAt(0);
064                    String ls=SystemUtil.getOSSpecificLineSeparator();
065                    
066                    if(firstR==' ' || firstR=='\t') return sub+ls+wrapLine(rest.length()>1?rest.substring(1):"",wrapTextLength);
067                    
068                    
069                    int indexSpace = sub.lastIndexOf(' ');
070                    int indexTab = sub.lastIndexOf('\t');
071                    int index=indexSpace<=indexTab?indexTab:indexSpace;
072                    
073                    if(index==-1) return sub+ls+wrapLine(rest,wrapTextLength);
074                    return sub.substring(0,index) + ls + wrapLine(sub.substring(index+1)+rest,wrapTextLength);
075                    
076            }       
077    }