1 /*******************************************************************************
\r
2 * ============LICENSE_START====================================================
\r
4 * * ===========================================================================
\r
5 * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
\r
6 * * ===========================================================================
\r
7 * * Licensed under the Apache License, Version 2.0 (the "License");
\r
8 * * you may not use this file except in compliance with the License.
\r
9 * * You may obtain a copy of the License at
\r
11 * * http://www.apache.org/licenses/LICENSE-2.0
\r
13 * * Unless required by applicable law or agreed to in writing, software
\r
14 * * distributed under the License is distributed on an "AS IS" BASIS,
\r
15 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
16 * * See the License for the specific language governing permissions and
\r
17 * * limitations under the License.
\r
18 * * ============LICENSE_END====================================================
\r
20 * * ECOMP is a trademark and service mark of AT&T Intellectual Property.
\r
22 ******************************************************************************/
\r
23 package com.att.authz.local;
\r
25 import java.io.File;
\r
26 import java.io.FileNotFoundException;
\r
27 import java.io.IOException;
\r
28 import java.io.RandomAccessFile;
\r
29 import java.util.Iterator;
\r
31 import com.att.authz.env.AuthzTrans;
\r
32 import com.att.authz.local.DataFile.Token;
\r
33 import com.att.authz.local.DataFile.Token.Field;
\r
34 import com.att.inno.env.Env;
\r
35 import com.att.inno.env.TimeTaken;
\r
37 public abstract class AbsData implements Iterable<String> {
\r
38 protected DataFile data;
\r
39 protected TextIndex ti;
\r
40 private File dataf,idxf,lockf;
\r
41 private String name;
\r
43 private int maxLineSize;
\r
44 private int fieldOffset;
\r
45 private int skipLines;
\r
47 public AbsData(File dataf,char sepChar, int maxLineSize, int fieldOffset) {
\r
48 File dir = dataf.getParentFile();
\r
49 int dot = dataf.getName().lastIndexOf('.');
\r
51 name = dataf.getName().substring(0,dot);
\r
55 this.delim = sepChar;
\r
56 this.maxLineSize = maxLineSize;
\r
57 this.fieldOffset = fieldOffset;
\r
58 idxf = new File(dir,name.concat(".idx"));
\r
59 lockf = new File(dir,name.concat(".lock"));
\r
62 data = new DataFile(dataf,"r");
\r
63 ti = new TextIndex(idxf);
\r
67 public void skipLines(int lines) {
\r
71 public String name() {
\r
75 public void open(AuthzTrans trans, long timeout) throws IOException {
\r
76 TimeTaken tt = trans.start("Open Data File", Env.SUB);
\r
77 boolean opened = false, first = true;
\r
79 if(!dataf.exists()) {
\r
80 throw new FileNotFoundException("Data File Missing:" + dataf.getCanonicalPath());
\r
82 long begin = System.currentTimeMillis();
\r
83 long end = begin+timeout;
\r
85 while((exists=lockf.exists()) && begin<end) {
\r
87 trans.warn().log("Waiting for",lockf.getCanonicalPath(),"to close");
\r
92 } catch (InterruptedException e) {
\r
95 begin = System.currentTimeMillis();
\r
98 throw new IOException(lockf.getCanonicalPath() + "exists. May not open Datafile");
\r
102 ensureIdxGood(trans);
\r
103 } catch (IOException e) {
\r
114 throw new IOException("DataFile pair for " + name + " was not able to be opened in " + timeout + "ms");
\r
118 private synchronized void ensureIdxGood(AuthzTrans trans) throws IOException {
\r
119 if(!idxf.exists() || idxf.length()==0 || dataf.lastModified()>idxf.lastModified()) {
\r
120 trans.warn().log(idxf.getCanonicalPath(),"is missing, empty or out of date, creating");
\r
121 RandomAccessFile raf = new RandomAccessFile(lockf, "rw");
\r
123 ti.create(trans, data, maxLineSize, delim, fieldOffset, skipLines);
\r
124 if(!idxf.exists() || (idxf.length()==0 && dataf.length()!=0)) {
\r
125 throw new IOException("Data Index File did not create correctly");
\r
134 public void close(AuthzTrans trans) throws IOException {
\r
139 public class Reuse {
\r
140 private Token tokenData;
\r
141 private Field fieldData;
\r
143 private Reuse(int size,char delim) {
\r
144 tokenData = data.new Token(size);
\r
145 fieldData = getTokenData().new Field(delim);
\r
148 public void reset() {
\r
149 getFieldData().reset();
\r
152 public void pos(int rec) {
\r
153 getFieldData().reset();
\r
154 getTokenData().pos(rec);
\r
157 public String next() {
\r
158 return getFieldData().next();
\r
161 public String at(int field) {
\r
162 return getFieldData().at(field);
\r
165 public String atToEnd(int field) {
\r
166 return getFieldData().atToEnd(field);
\r
169 public Field getFieldData() {
\r
173 public Token getTokenData() {
\r
179 public Reuse reuse() {
\r
180 return new Reuse(maxLineSize,delim);
\r
183 public Iter iterator() {
\r
187 public class Iter implements Iterator<String> {
\r
188 private Reuse reuse;
\r
189 private com.att.authz.local.TextIndex.Iter tii;
\r
193 tii = ti.new Iter();
\r
197 public boolean hasNext() {
\r
198 return tii.hasNext();
\r
202 public String next() {
\r
204 int rec = tii.next();
\r
206 return reuse.at(0);
\r
210 public void remove() {
\r