View Javadoc

1   package org.csc.phynixx.tutorial;
2   
3   /*
4    * #%L
5    * phynixx-common
6    * %%
7    * Copyright (C) 2014 csc
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  
24  import org.csc.phynixx.common.exceptions.DelegatedRuntimeException;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.RandomAccessFile;
29  import java.nio.channels.Channel;
30  import java.nio.channels.FileChannel;
31  import java.util.ArrayList;
32  import java.util.List;
33  import java.util.concurrent.locks.Condition;
34  import java.util.concurrent.locks.Lock;
35  import java.util.concurrent.locks.ReentrantLock;
36  
37  /**
38   *Implements an quit simple an cooperating lock. To have acces to write to the file, you have to aquire a lock. If the lock is successful, you gain an lockToken. This token identifies the lock and this token enables you to release the token.
39   * If the file is lock all method to write/rad the file are unsynchronized to improve performance.
40   */
41  public class UTFWriterImpl implements UTFWriter {
42  
43  
44      Lock lock = new ReentrantLock();
45  
46      private Condition unlocked = lock.newCondition();
47  
48      private String lockToken = null;
49  
50      /**
51       * Das RandomAccessFile, dass zum Schreiben u. Lesen geoeffnet wird.
52       */
53      private RandomAccessFile raf = null;
54  
55      private File file;
56  
57      public UTFWriterImpl(File file) {
58          this.open(file);
59      }
60  
61      /**
62       * @return lockToken you need to identify the unlock
63       */
64      public String lock() throws InterruptedException {
65  
66          lock.lock();
67          try {
68              System.out.println("Locking Thread " + Thread.currentThread().getId());
69              while (lockToken != null) {
70                  unlocked.await();
71              }
72              lockToken = Long.toString(System.currentTimeMillis());
73  
74              System.out.println("Lock acquired  Thread " + Thread.currentThread().getId());
75  
76              return lockToken;
77  
78          } finally {
79              lock.unlock();
80          }
81  
82      }
83  
84      /**
85       *
86       * @param lockToken identifing the lock
87       */
88      public void unlock(String lockToken) {
89  
90          lock.lock();
91          try {
92              System.out.println("Unlocking Thread " + Thread.currentThread().getId());
93              if (this.lockToken != null) {
94                  if (!this.lockToken.equals(lockToken)) {
95                      throw new IllegalStateException("The lock token " + lockToken + " isn#T equals to the cuirrent locktoken " + this.lockToken);
96                  }
97                  this.lockToken = null;
98              }
99              unlocked.signalAll();
100             System.out.println("Unlocking successful Thread " + Thread.currentThread().getId());
101 
102         } finally {
103             lock.unlock();
104         }
105     }
106 
107     /**
108      * Schliesst die Datei und den FileChannel
109      */
110     @Override
111     public void close() {
112 
113         if (raf != null) {
114             // close Quietly
115             try {
116                 // Schliessen der Daten-Datei
117                 raf.close();
118                 file = null;
119             } catch (Exception e) {
120             } finally {
121                 raf = null;
122             }
123         }
124     }
125 
126     @Override
127     public String getFilename() throws IOException {
128         return this.file.getCanonicalPath();
129     }
130 
131     /**
132      * zeigt an, ob die Instanz geschlossen ist
133      *
134      * @return true wenn die Datei geschlossen ist
135      */
136     @Override
137     public boolean isClosed() {
138         return (this.raf == null);
139     }
140 
141 
142     @Override
143     public void resetContent() throws IOException {
144 
145         if (this.isClosed()) {
146             throw new IllegalStateException("Writer is closed");
147         }
148         this.getRandomAccessFile().getChannel().truncate(0);
149     }
150 
151     @Override
152     public long write(String value) throws IOException {
153         if (value == null) {
154             throw new IllegalArgumentException("value must not be null");
155         }
156         this.getRandomAccessFile().writeUTF(value);
157 
158         return  this.getRandomAccessFile().getChannel().position();
159     }
160 
161     @Override
162     public List<String> readContent() throws IOException {
163 
164         List<String> content = new ArrayList<String>();
165 
166         // start from beginning
167         this.getRandomAccessFile().getChannel().position(0l);
168 
169         long size = this.getRandomAccessFile().getChannel().size();
170 
171         while (position() < size) {
172             String value = this.getRandomAccessFile().readUTF();
173             content.add(value);
174         }
175         return content;
176     }
177 
178 
179     @Override
180     public long size() throws IOException {
181         return this.getRandomAccessFile().getChannel().size();
182     }
183 
184     @Override
185     public void restoreSize(long filePosition) throws IOException {
186         this.getRandomAccessFile().getChannel().truncate(filePosition);
187         this.getRandomAccessFile().getChannel().position(filePosition);
188     }
189 
190 
191     RandomAccessFile getRandomAccessFile() {
192         if (this.isClosed()) {
193             throw new IllegalStateException("RandomAccessFile is close");
194         }
195 
196         return raf;
197     }
198 
199 
200 
201     private void open(File file) {
202         try {
203             this.raf = new RandomAccessFile(file, "rw");
204             this.file = file;
205         } catch (Exception e) {
206             throw new DelegatedRuntimeException(e);
207         }
208     }
209 
210 
211     @Override
212     public long position() throws IOException {
213         return this.raf.getChannel().position();
214     }
215 
216 
217     @Override
218     public String toString() {
219         return "UTFWriterImpl{" +
220                 "file='" + file + '\'' +
221                 '}';
222     }
223 
224 
225 }