001: /*
002: * $Id: DataFile.java,v 1.2 2003/12/03 05:12:10 jonesde Exp $
003: *
004: * Copyright (c) 2001-2003 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.datafile;
026:
027: import java.io.BufferedReader;
028: import java.io.ByteArrayInputStream;
029: import java.io.ByteArrayOutputStream;
030: import java.io.File;
031: import java.io.FileNotFoundException;
032: import java.io.FileOutputStream;
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.InputStreamReader;
036: import java.io.OutputStream;
037: import java.net.URL;
038: import java.util.ArrayList;
039: import java.util.List;
040: import java.util.Stack;
041:
042: import org.ofbiz.base.util.Debug;
043:
044: /**
045: * DataFile main class
046: *
047: * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
048: * @version $Revision: 1.2 $
049: * @since 2.0
050: */
051:
052: public class DataFile {
053:
054: public static final String module = DataFile.class.getName();
055:
056: /** List of record in the file, contains Record objects */
057: protected List records = new ArrayList();
058:
059: /** Contains the definition for the file */
060: protected ModelDataFile modelDataFile;
061:
062: /** Creates a DataFile object which will contain the parsed objects for the specified datafile, using the specified definition.
063: * @param fileUrl The URL where the data file is located
064: * @param definitionUrl The location of the data file definition XML file
065: * @param dataFileName The data file model name, as specified in the definition XML file
066: * @throws DataFileException Exception thown for various errors, generally has a nested exception
067: * @return A new DataFile object with the specified file pre-loaded
068: */
069: public static DataFile readFile(URL fileUrl, URL definitionUrl,
070: String dataFileName) throws DataFileException {
071: DataFile dataFile = makeDataFile(definitionUrl, dataFileName);
072:
073: dataFile.readDataFile(fileUrl);
074: return dataFile;
075: }
076:
077: /** Creates a DataFile object using the specified definition.
078: * @param definitionUrl The location of the data file definition XML file
079: * @param dataFileName The data file model name, as specified in the definition XML file
080: * @throws DataFileException Exception thown for various errors, generally has a nested exception
081: * @return A new DataFile object
082: */
083: public static DataFile makeDataFile(URL definitionUrl,
084: String dataFileName) throws DataFileException {
085: ModelDataFileReader reader = ModelDataFileReader
086: .getModelDataFileReader(definitionUrl);
087:
088: if (reader == null) {
089: throw new DataFileException(
090: "Could not load definition file located at \""
091: + definitionUrl + "\"");
092: }
093: ModelDataFile modelDataFile = reader
094: .getModelDataFile(dataFileName);
095:
096: if (modelDataFile == null) {
097: throw new DataFileException(
098: "Could not find file definition for data file named \""
099: + dataFileName + "\"");
100: }
101: DataFile dataFile = new DataFile(modelDataFile);
102:
103: return dataFile;
104: }
105:
106: /** Construct a DataFile object setting the model, does not load it
107: * @param modelDataFile The model of the DataFile to instantiate
108: */
109: public DataFile(ModelDataFile modelDataFile) {
110: this .modelDataFile = modelDataFile;
111: }
112:
113: protected DataFile() {
114: }
115:
116: public ModelDataFile getModelDataFile() {
117: return modelDataFile;
118: }
119:
120: public List getRecords() {
121: return records;
122: }
123:
124: public void addRecord(Record record) {
125: records.add(record);
126: }
127:
128: public Record makeRecord(String recordName) {
129: ModelRecord modelRecord = getModelDataFile().getModelRecord(
130: recordName);
131: return new Record(modelRecord);
132: }
133:
134: /** Loads (or reloads) the data file at the pre-specified location.
135: * @param fileUrl The URL that the file will be loaded from
136: * @throws DataFileException Exception thown for various errors, generally has a nested exception
137: */
138: public void readDataFile(URL fileUrl) throws DataFileException {
139: if (fileUrl == null) {
140: throw new IllegalStateException(
141: "File URL is null, cannot load file");
142: }
143:
144: RecordIterator recordIterator = this
145: .makeRecordIterator(fileUrl);
146: while (recordIterator.hasNext()) {
147: this .records.add(recordIterator.next());
148: }
149: // no need to manually close the stream since we are reading to the end of the file: recordIterator.close();
150: }
151:
152: /** Populates (or reloads) the data file with the text of the given content
153: * @param content The text data to populate the DataFile with
154: * @throws DataFileException Exception thown for various errors, generally has a nested exception
155: */
156: public void readDataFile(String content) throws DataFileException {
157: if (content == null || content.length() <= 0)
158: throw new IllegalStateException(
159: "Content is empty, can't read file");
160:
161: ByteArrayInputStream bis = new ByteArrayInputStream(content
162: .getBytes());
163:
164: readDataFile(bis, null);
165: }
166:
167: /** Loads (or reloads) the data file from the given stream
168: * @param dataFileStream A stream containing the text data for the data file
169: * @param locationInfo Text information about where the data came from for exception messages
170: * @throws DataFileException Exception thown for various errors, generally has a nested exception
171: */
172: public void readDataFile(InputStream dataFileStream,
173: String locationInfo) throws DataFileException {
174: if (modelDataFile == null) {
175: throw new IllegalStateException(
176: "DataFile model is null, cannot load file");
177: }
178: if (locationInfo == null) {
179: locationInfo = "unknown";
180: }
181:
182: RecordIterator recordIterator = this .makeRecordIterator(
183: dataFileStream, locationInfo);
184: while (recordIterator.hasNext()) {
185: this .records.add(recordIterator.next());
186: }
187: // no need to manually close the stream since we are reading to the end of the file: recordIterator.close();
188: }
189:
190: public RecordIterator makeRecordIterator(URL fileUrl)
191: throws DataFileException {
192: return new RecordIterator(fileUrl, this .modelDataFile);
193: }
194:
195: public RecordIterator makeRecordIterator(
196: InputStream dataFileStream, String locationInfo)
197: throws DataFileException {
198: return new RecordIterator(dataFileStream, this .modelDataFile,
199: locationInfo);
200: }
201:
202: /** Writes the records in this DataFile object to a text data file
203: * @param filename The filename to put the data into
204: * @throws DataFileException Exception thown for various errors, generally has a nested exception
205: */
206: public void writeDataFile(String filename) throws DataFileException {
207: File outFile = new File(filename);
208: FileOutputStream fos = null;
209:
210: try {
211: fos = new FileOutputStream(outFile);
212: } catch (FileNotFoundException e) {
213: throw new DataFileException("Could not open file "
214: + filename, e);
215: }
216:
217: try {
218: writeDataFile(fos);
219: } finally {
220: try {
221: if (fos != null)
222: fos.close();
223: } catch (IOException e) {
224: throw new DataFileException("Could not close file "
225: + filename
226: + ", may not have written correctly;", e);
227: }
228: }
229: }
230:
231: /** Returns the records in this DataFile object as a plain text data file content
232: * @throws DataFileException Exception thown for various errors, generally has a nested exception
233: * @return A String containing what would go into a data file as plain text
234: */
235: public String writeDataFile() throws DataFileException {
236: ByteArrayOutputStream bos = new ByteArrayOutputStream();
237:
238: writeDataFile(bos);
239: String outString = bos.toString();
240:
241: try {
242: if (bos != null)
243: bos.close();
244: } catch (IOException e) {
245: Debug.logWarning(e, module);
246: }
247: return outString;
248: }
249:
250: /** Writes the records in this DataFile object to the given OutputStream
251: * @param outStream The Stream to put the data into
252: * @throws DataFileException Exception thown for various errors, generally has a nested exception
253: */
254: public void writeDataFile(OutputStream outStream)
255: throws DataFileException {
256: writeRecords(outStream, this .records);
257: }
258:
259: protected void writeRecords(OutputStream outStream, List records)
260: throws DataFileException {
261: for (int r = 0; r < records.size(); r++) {
262: Record record = (Record) records.get(r);
263: String line = record.writeLineString(modelDataFile);
264:
265: try {
266: outStream.write(line.getBytes());
267: } catch (IOException e) {
268: throw new DataFileException(
269: "Could not write to stream;", e);
270: }
271:
272: if (record.getChildRecords() != null
273: && record.getChildRecords().size() > 0) {
274: writeRecords(outStream, record.getChildRecords());
275: }
276: }
277: }
278: }
|