Sonar Fixes, Formatting
[aaf/authz.git] / auth / auth-core / src / main / java / org / onap / aaf / auth / local / AbsData.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.local;
23
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.io.RandomAccessFile;
28 import java.util.Iterator;
29 import java.util.NoSuchElementException;
30
31 import org.onap.aaf.auth.env.AuthzTrans;
32 import org.onap.aaf.auth.local.DataFile.Token;
33 import org.onap.aaf.auth.local.DataFile.Token.Field;
34 import org.onap.aaf.misc.env.Env;
35 import org.onap.aaf.misc.env.TimeTaken;
36
37 public abstract class AbsData implements Iterable<String> {
38     protected DataFile data;
39     protected TextIndex ti;
40     private File dataf,idxf,lockf;
41     private String name;
42     private char delim;
43     private int maxLineSize;
44     private int fieldOffset;
45     private int skipLines;
46
47     public AbsData(File dataf,char sepChar, int maxLineSize, int fieldOffset) {
48         File dir = dataf.getParentFile();
49         int dot = dataf.getName().lastIndexOf('.');
50         name = dataf.getName().substring(0,dot);
51
52         this.dataf=dataf;
53         this.delim = sepChar;
54         this.maxLineSize = maxLineSize;
55         this.fieldOffset = fieldOffset;
56         idxf = new File(dir,name.concat(".idx"));
57         lockf = new File(dir,name.concat(".lock"));
58
59
60         data = new DataFile(dataf,"r");
61         ti = new TextIndex(idxf);
62         skipLines=0;
63     }
64
65     public void skipLines(int lines) {
66         skipLines=lines;
67     }
68
69     public String name() {
70         return name;
71     }
72
73     public void open(AuthzTrans trans, long timeout) throws IOException {
74         TimeTaken tt = trans.start("Open Data File", Env.SUB);
75         boolean first = true;
76         try {
77                 if (!dataf.exists()) {
78                     throw new FileNotFoundException("Data File Missing:" + dataf.getCanonicalPath());
79                 }
80                 long begin = System.currentTimeMillis();
81                 long end = begin+timeout;
82                 boolean exists;
83                 while ((exists=lockf.exists()) && begin<end) {
84                     if (first) {
85                         trans.warn().log("Waiting for",lockf.getCanonicalPath(),"to close");
86                         first = false;
87                     }
88                     try {
89                         Thread.sleep(200);
90                     } catch (InterruptedException e) {
91                         Thread.currentThread().interrupt();
92                     }
93                     begin = System.currentTimeMillis();
94                 }
95                 if (exists) {
96                     throw new IOException(lockf.getCanonicalPath() + "exists.  May not open Datafile");
97                 }
98                 data.open();
99                 try {
100                     ensureIdxGood(trans);
101                 } catch (IOException e) {
102                     data.close();
103                     throw e;
104                 }
105                 ti.open();
106
107         } finally {
108             tt.done();
109         }
110     }
111
112     private synchronized void ensureIdxGood(AuthzTrans trans) throws IOException {
113         if (!idxf.exists() || idxf.length()==0 || dataf.lastModified()>idxf.lastModified()) {
114             trans.warn().log(idxf.getAbsolutePath(),"is missing, empty or out of date, creating");
115             RandomAccessFile raf = new RandomAccessFile(lockf, "rw");
116             try {
117                 ti.create(trans, data, maxLineSize, delim, fieldOffset, skipLines);
118                 if (!idxf.exists() || (idxf.length()==0 && dataf.length()!=0)) {
119                     throw new IOException("Data Index File did not create correctly");
120                 }
121             } finally {
122                 raf.close();
123                 lockf.delete();
124             }
125         }
126     }
127
128     public void close(AuthzTrans trans) throws IOException {
129         ti.close();
130         data.close();
131     }
132
133     public class Reuse {
134         public Token tokenData;
135         private Field fieldData;
136
137         private Reuse(int size,char delim) {
138             tokenData = data.new Token(size);
139             fieldData = tokenData.new Field(delim);
140         }
141
142         public void reset() {
143             getFieldData().reset();
144         }
145
146         public void pos(int rec) {
147             getFieldData().reset();
148             tokenData.pos(rec);
149         }
150
151         public String next() {
152             return getFieldData().next();
153         }
154
155         public String at(int field) {
156             return getFieldData().at(field);
157         }
158
159         public String atToEnd(int field) {
160             return getFieldData().atToEnd(field);
161         }
162
163         public Field getFieldData() {
164             return fieldData;
165         }
166     }
167
168     public Reuse reuse() {
169         return new Reuse(maxLineSize,delim);
170     }
171
172     public Iter iterator() {
173         return new Iter();
174     }
175
176     public class Iter implements Iterator<String> {
177         private Reuse reuse;
178         private org.onap.aaf.auth.local.TextIndex.Iter tii;
179
180         public Iter() {
181             reuse = reuse();
182             tii = ti.new Iter();
183         }
184
185         @Override
186         public boolean hasNext() {
187             return tii.hasNext();
188         }
189
190         @Override
191         public String next() {
192             if (!hasNext()) {
193                 throw new NoSuchElementException();
194             }
195             reuse.reset();
196             int rec = tii.next();
197             reuse.pos(rec);
198             return reuse.at(0);
199         }
200
201         @Override
202         public void remove() {
203             // read only
204         }
205     }
206 }