001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.commons.io.res.util;
020
021import java.io.IOException;
022import java.io.InputStream;
023
024import lucee.commons.io.res.Resource;
025
026
027/**
028 * this class holds information about a snippet from text with its start and end line numbers
029 */
030public class ResourceSnippet implements java.io.Serializable {
031
032    private String text = null;
033    private int startLine = 0, endLine =0;
034
035    public final static ResourceSnippet Empty = new ResourceSnippet( "", 0, 0 );
036
037    public ResourceSnippet(String text, int startLine, int endLine) {
038
039        this.text = text;
040        this.startLine = startLine;
041        this.endLine = endLine;
042    }
043
044    /** returns the actual text of the snippet */
045    public String getContent() {
046
047        return text;
048    }
049
050    /** returns the start line number */
051    public int getStartLine() {
052
053        return startLine;
054    }
055
056    /** returns the end line number */
057    public int getEndLine() {
058
059        return endLine;
060    }
061
062
063    public static String getContents( InputStream is, String charset ) {
064
065        String result;
066
067        java.util.Scanner scanner = new java.util.Scanner( is, charset ).useDelimiter( "\\A" );
068        result  = scanner.hasNext() ? scanner.next() : "";
069
070        if ( is != null ) try {
071
072            is.close();
073        }
074        catch ( IOException ex ) {}
075
076        return result;
077    }
078
079
080    public static String getContents( Resource res, String charset ) {
081
082        try {
083
084            return getContents( res.getInputStream(), charset );
085        }
086        catch (IOException ex) {
087
088            return "";
089        }
090    }
091
092
093    public static ResourceSnippet createResourceSnippet( String src, int startChar, int endChar ) {
094
095        String text = "";
096        if ( endChar > startChar && endChar <= src.length() )
097            text = src.substring( startChar, endChar );
098
099        return new ResourceSnippet( text, getLineNumber( src, startChar ), getLineNumber( src, endChar ) );
100    }
101
102
103    /** extract a ResourceSnippet from InputStream at the given char positions
104     *
105     * @param is - InputStream of the Resource
106     * @param startChar - start position of the snippet
107     * @param endChar - end position of the snippet
108     * @param charset - use server's charset, default should be UTF-8
109     * @return
110     */
111    public static ResourceSnippet createResourceSnippet( InputStream is, int startChar, int endChar, String charset ) {
112
113        return createResourceSnippet( getContents( is, charset ), startChar, endChar );
114    }
115
116    /** extract a ResourceSnippet from a Resource at the given char positions
117     *
118     * @param res - Resource from which to extract the snippet
119     * @param startChar - start position of the snippet
120     * @param endChar - end position of the snippet
121     * @param charset - use server's charset, default should be UTF-8
122     * @return
123     */
124    public static ResourceSnippet createResourceSnippet( Resource res, int startChar, int endChar, String charset ) {
125
126        try {
127
128            return createResourceSnippet( res.getInputStream(), startChar, endChar, charset );
129        }
130        catch ( IOException ex ) {
131
132            return ResourceSnippet.Empty;
133        }
134    }
135
136    /** returns the line number of the given char in the text */
137    public static int getLineNumber( String text, int posChar ) {
138
139        int len = Math.min( posChar, text.length() );
140        int result = 1;
141
142        for ( int i=0; i<len; i++ ) {
143
144            if ( text.charAt( i ) == '\n' )
145                result++;
146        }
147
148        return result;
149    }
150}