1   package net.sf.jpkgmk;
2   
3   import java.io.File;
4   import java.io.FileInputStream;
5   import java.io.IOException;
6   import java.io.InputStream;
7   import java.io.InputStreamReader;
8   import java.io.Reader;
9   import java.io.StringReader;
10  import java.nio.charset.Charset;
11  
12  import net.sf.jpkgmk.util.LineCountingReader;
13  import net.sf.jpkgmk.util.StreamUtil;
14  import net.sf.jpkgmk.util.StringUtil;
15  
16  import org.apache.commons.logging.Log;
17  import org.apache.commons.logging.LogFactory;
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  public abstract class AbstractParser<T> 
29  {
30  	public static final char DEFAULT_LINE_DELIMITER = ' ';
31  
32  	private Log log = LogFactory.getLog(AbstractParser.class);
33  
34  	
35  	public AbstractParser()
36  	{
37  	}
38  	
39  	
40  	
41  
42  
43  
44  
45  
46  
47  	public T parse(String data) throws IOException
48  	{
49  		return parse(new StringReader(data));
50  	}
51  	
52  	
53  
54  
55  
56  
57  
58  
59  	public T parse(File file) throws IOException
60  	{
61  		if (file == null) {
62  			throw new NullPointerException(
63  					"The parameter 'file' must not be null");
64  		}
65  		
66  		InputStream inputStream = new FileInputStream(file);
67  		try {
68  			Charset charset = Charset.forName("US-ASCII");
69  			log.info("Using default character set " + charset + " for reading file " + file);
70  			Reader reader = new InputStreamReader(inputStream, charset);
71  			return this.parse(reader);
72  		}
73  		finally {
74  			StreamUtil.tryCloseStream(inputStream);
75  		}
76  	}
77  
78  	
79  
80  
81  
82  
83  
84  	public T parse(Reader data) throws IOException
85  	{
86  		if (data == null) {
87  			throw new NullPointerException(
88  					"The parameter 'data' must not be null");
89  		}
90  
91  		T result = createResult();
92  		
93  		LineCountingReader reader = new LineCountingReader(data);
94  		try {
95  			String line = null;
96  			while((line=reader.readLine()) != null) {
97  				if(StringUtil.isNullOrEmpty(line)) {
98  					log.debug("Ignoring empty line " + reader.currentLineNumber());
99  					continue;
100 				}
101 				
102 				try {
103 					this.parseAndAddLine(line, result);
104 				}
105 				catch(Exception e) {
106 					throw new PackageException("Exception while parsing line " + reader.currentLineNumber() + ": " + e, e);
107 				}
108 			}
109 		}
110 		finally {
111 			StreamUtil.tryCloseStream(reader);
112 		}
113 		return result;
114 	}
115 	
116 	
117 	protected abstract T createResult();
118 
119 
120 	protected abstract void parseAndAddLine(String line, T resultObject);
121 	
122 
123 	
124 
125 
126 
127 
128 	public static final String[] getLineItems(String line)
129 	{
130 		String[] items = line.split(String.valueOf(DEFAULT_LINE_DELIMITER));
131 		return items;
132 	}
133 
134 }