View Javadoc

1   /**
2    * Copyright 2011 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.common.impex.data.impl;
17  
18  import java.io.BufferedReader;
19  import java.io.IOException;
20  import java.util.List;
21  
22  import org.apache.commons.io.IOUtils;
23  import org.apache.commons.lang3.StringUtils;
24  import org.kuali.common.impex.data.MpxHeaderData;
25  import org.kuali.common.impex.data.SqlProducer;
26  import org.kuali.common.impex.model.Schema;
27  import org.kuali.common.impex.model.Table;
28  import org.kuali.common.jdbc.SqlMetaData;
29  import org.kuali.common.jdbc.supplier.AbstractSupplier;
30  import org.kuali.common.jdbc.supplier.LocationSupplier;
31  import org.kuali.common.jdbc.supplier.LocationSupplierUtils;
32  import org.kuali.common.util.CollectionUtils;
33  import org.kuali.common.util.LocationUtils;
34  import org.kuali.common.util.TextMetaData;
35  
36  /**
37   * This class provides an implementation of the SqlSupplier interface using an Mpx resource as the data source
38   * 
39   * @author andrewlubbers
40   */
41  public class MpxLocationSupplier extends AbstractSupplier implements LocationSupplier {
42  
43  	public static final String DEFAULT_MPX_EXTENSION = ".mpx";
44  	public static final String UTF8 = "UTF-8";
45  
46  	protected BufferedReader reader;
47  	protected Table table;
48      protected MpxHeaderData headerData;
49  
50  	String extension = DEFAULT_MPX_EXTENSION;
51  	String encoding = UTF8;
52  	SqlProducer producer;
53  	String location;
54  
55      /**
56       * Data model provider
57       */
58      Schema schema;
59  
60  	@Override
61  	public void open() throws IOException {
62  		this.table = getTable();
63  		this.reader = LocationUtils.getBufferedReader(getResourceLocation(), encoding);
64          this.headerData = getHeader(reader);
65  	}
66  
67      protected String getResourceLocation() {
68          return LocationSupplierUtils.getLocationFromContextLocation(location);
69      }
70  
71  	@Override
72  	public List<String> getSql() throws IOException {
73  		return producer.getSql(table, headerData, reader);
74  	}
75  
76  	@Override
77  	public void close() {
78  		IOUtils.closeQuietly(reader);
79  		this.table = null;
80  	}
81  
82  	protected Table getTable() {
83  
84          String resourceLocation = getResourceLocation();
85  
86  		String filename = LocationUtils.getFilename(resourceLocation);
87  		if (!StringUtils.endsWithIgnoreCase(filename, extension)) {
88  			throw new IllegalArgumentException(resourceLocation + " does not end with " + extension);
89  		}
90  		int end = filename.length() - extension.length();
91  		String tableName = StringUtils.substring(filename, 0, end);
92  
93          for (Table t : schema.getTables()) {
94              if(t.getName().equalsIgnoreCase(tableName)) {
95                  return t;
96              }
97          }
98  
99          throw new IllegalArgumentException("Unable to locate table [" + tableName + "]");
100 	}
101 
102     @Override
103 	public void fillInMetaData() {
104 		TextMetaData tmd = LocationUtils.getTextMetaData(getResourceLocation());
105 		this.metaData = new SqlMetaData(tmd.getLines() - 1, tmd.getSize());
106 	}
107 
108     /**
109      * Parses the next line in the given reader and returns a MpxHeaderData built from header information
110      *
111      * This method assumes the given reader is at the beginning of an mpx file
112      *
113      * @param reader the mpx file reader
114      * @return the next parsed header data
115      * @throws IllegalArgumentException when the next non-blank line from the reader is not a header line
116      *      IOException if a read error is thrown from the reader
117      */
118     protected MpxHeaderData getHeader(BufferedReader reader) throws IOException {
119         String line = reader.readLine();
120         while(org.codehaus.plexus.util.StringUtils.isBlank(line)) {
121             line = reader.readLine();
122         }
123 
124         if (ParseUtils.isHeaderLine(line)) {
125             MpxHeaderData header = new MpxHeaderData();
126             header.getColumnNames().addAll(CollectionUtils.getTrimmedListFromCSV(line));
127 
128             return header;
129         }
130         else {
131             throw new IllegalArgumentException("Could not parse mpx header, next non-blank in given reader is not a header line.  Reached line was: " + line);
132         }
133     }
134 
135 	public String getEncoding() {
136 		return encoding;
137 	}
138 
139 	public void setEncoding(String encoding) {
140 		this.encoding = encoding;
141 	}
142 
143 	@Override
144 	public String getLocation() {
145 		return location;
146 	}
147 
148 	@Override
149 	public void setLocation(String location) {
150 		this.location = location;
151 	}
152 
153 	public SqlProducer getProducer() {
154 		return producer;
155 	}
156 
157 	public void setProducer(SqlProducer producer) {
158 		this.producer = producer;
159 	}
160 
161 	public String getExtension() {
162 		return extension;
163 	}
164 
165 	public void setExtension(String extension) {
166 		this.extension = extension;
167 	}
168 
169     public Schema getSchema() {
170         return schema;
171     }
172 
173     public void setSchema(Schema schema) {
174         this.schema = schema;
175     }
176 }