Beautiful Code [248]
75 if (reader != null) {
76 DataBlock block = null;
77
78 try {
79 block = reader.readDataBlock( );
80 }
81 catch(MiddlewareException ex) {
82 Globals.streamerLogger.error("Streamer.readDataBlock("
83 + key + ")", ex);
84 cacheStats.incrementFileErrorCount( );
85 removeReader(key, reader);
86 throw ex;
87 }
88
89 // End of file?
90 if (block == null) {
91 removeReader(key, reader);
92 }
93
94 cacheStats.incrementTotalServerResponseTime(startTime);
95 return block;
96 }
97 else {
98 throw new MiddlewareException(
99 "Download source file not opened: " +
100 fileToken.getFilePath( ));
101 }
102 }
103
The registerNewReader( ) and removeReader( ) methods create and destroy the stateful file reader beans, respectively:
Code View: Scroll / Show All
104 private static FileReaderLocal registerNewReader(String key)
105 throws Exception
106 {
107 Context context = MiddlewareUtility.getInitialContext( );
108 Object queryRef = context.lookup("FileReaderLocal");
109
110 // Create the reader service bean and register it.
111 FileReaderLocalHome home = (FileReaderLocalHome)
112 PortableRemoteObject.narrow(queryRef, FileReaderLocalHome.class);
113 FileReaderLocal reader = home.create( );
114
115 synchronized (readerTable) {
116 readerTable.put(key, reader);
117 }
118
119 return reader;
120 }
121
122 private static void removeReader(String key, FileReaderLocal reader)
123 {
124 synchronized (readerTable) {
125 readerTable.remove(key);
126 }
127
128 if (reader != null) {
129 try {
130 reader.remove( );
131 }
132 catch(javax.ejb.NoSuchObjectLocalException ex) {
133 // ignore
134 }
135 catch(Exception ex) {
136 Globals.streamerLogger.error("Streamer.removeReader("
137 + key + ")", ex);
138 cacheStats.incrementFileErrorCount( );
139 }
140 }
141 }
142 }
Now, here are code snippets from the file reader bean. The cacheStats and fileStats fields are for runtime monitoring, as described later. The getDataFile( ) method logs the start of the file download (lines 160–161):
Code View: Scroll / Show All
143 public class FileReaderBean implements SessionBean
144 {
145 private static final String FILE = "file";
146
147 private transient static BeanCacheStats cacheStats = Globals.queryStats;
148 private transient static FileStats fileStats = Globals.fileStats;
149
150 private transient int totalSize;
151 private transient String type;
152 private transient String name;
153 private transient FileInputStream fileInputStream;
154 private transient BufferedInputStream inputStream;
155 private transient boolean sawEnd;
156
157 public void getDataFile(String filePath)
158 throws MiddlewareException
159 {
160 Globals.streamerLogger.debug("Begin download of file '"
161 + filePath + "'");
162 this.type = FILE;
163 this.name = filePath;
164 this.sawEnd = false;
165
166 try {
167
168 // Create an input stream from the data file.
169 fileInputStream = new FileInputStream(new File(filePath));
170 inputStream = new BufferedInputStream(fileInputStream);
171
172 fileStats.startDownload(this, FILE, name);
173 }
174 catch(Exception ex) {
175 close( );
176 throw new MiddlewareException(ex);
177 }
178 }
179
The readDataBlock( ) method reads each data block from the source file. When it has read the entire source file, it logs the completion (lines 191–193):
Code View: Scroll / Show All
180 public DataBlock readDataBlock( )
181 throws MiddlewareException
182 {
183 byte buffer[] = new byte[Globals.streamerBlockSize];
184
185 try {
186 int size = inputStream.read(buffer);
187
188 if (size == -1) {
189 close( );
190
191 Globals.streamerLogger.debug("Completed download of " +
192 type + " '" + name + "': " +
193 totalSize + " bytes");
194
195 cacheStats.incrementFileDownloadedCount( );
196 cacheStats.incrementFileByteCount(totalSize);
197 fileStats.endDownload(this, totalSize);
198
199 sawEnd = true;
200 return null;
201 }
202 else {
203 DataBlock block = new DataBlock(size, buffer);