Update project structure to org.onap.aaf
[aaf/authz.git] / authz-core / src / main / java / org / onap / aaf / authz / local / AbsData.java
diff --git a/authz-core/src/main/java/org/onap/aaf/authz/local/AbsData.java b/authz-core/src/main/java/org/onap/aaf/authz/local/AbsData.java
new file mode 100644 (file)
index 0000000..30231b8
--- /dev/null
@@ -0,0 +1,215 @@
+/*******************************************************************************\r
+ * ============LICENSE_START====================================================\r
+ * * org.onap.aaf\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.onap.aaf.authz.local;\r
+\r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.RandomAccessFile;\r
+import java.util.Iterator;\r
+\r
+import org.onap.aaf.authz.env.AuthzTrans;\r
+import org.onap.aaf.authz.local.DataFile.Token;\r
+import org.onap.aaf.authz.local.DataFile.Token.Field;\r
+\r
+import org.onap.aaf.inno.env.Env;\r
+import org.onap.aaf.inno.env.TimeTaken;\r
+\r
+public abstract class AbsData implements Iterable<String> {\r
+       protected DataFile data;\r
+       protected TextIndex ti;\r
+       private File dataf,idxf,lockf;\r
+       private String name;\r
+       private char delim;\r
+       private int maxLineSize;\r
+       private int fieldOffset;\r
+       private int skipLines;\r
+\r
+       public AbsData(File dataf,char sepChar, int maxLineSize, int fieldOffset) {\r
+               File dir = dataf.getParentFile();\r
+               int dot = dataf.getName().lastIndexOf('.');\r
+               if(dot>=0) {\r
+                       name = dataf.getName().substring(0,dot);\r
+               }\r
+\r
+               this.dataf=dataf;\r
+               this.delim = sepChar;\r
+               this.maxLineSize = maxLineSize;\r
+               this.fieldOffset = fieldOffset;\r
+               idxf = new File(dir,name.concat(".idx"));\r
+               lockf = new File(dir,name.concat(".lock"));\r
+               \r
+               \r
+               data = new DataFile(dataf,"r");\r
+               ti = new TextIndex(idxf);\r
+               skipLines=0;\r
+       }\r
+       \r
+       public void skipLines(int lines) {\r
+               skipLines=lines;\r
+       }\r
+       \r
+       public String name() {\r
+               return name;\r
+       }\r
+       \r
+       public void open(AuthzTrans trans, long timeout) throws IOException {\r
+               TimeTaken tt = trans.start("Open Data File", Env.SUB);\r
+               boolean opened = false, first = true;\r
+               try {\r
+                               if(!dataf.exists()) {\r
+                                       throw new FileNotFoundException("Data File Missing:" + dataf.getCanonicalPath());\r
+                               }\r
+                               long begin = System.currentTimeMillis();\r
+                               long end = begin+timeout;\r
+                               boolean exists;\r
+                               while((exists=lockf.exists()) && begin<end) {\r
+                                       if(first) {\r
+                                               trans.warn().log("Waiting for",lockf.getCanonicalPath(),"to close");\r
+                                               first = false;\r
+                                       } \r
+                                       try {\r
+                                               Thread.sleep(200);\r
+                                       } catch (InterruptedException e) {\r
+                                               break;\r
+                                       }\r
+                                       begin = System.currentTimeMillis();\r
+                               }\r
+                               if(exists) {\r
+                                       throw new IOException(lockf.getCanonicalPath() + "exists.  May not open Datafile");\r
+                               }\r
+                               data.open();\r
+                               try {\r
+                                       ensureIdxGood(trans);\r
+                               } catch (IOException e) {\r
+                                       data.close();\r
+                                       throw e;\r
+                               }\r
+                               ti.open();\r
+                               opened = true;\r
+                       \r
+               } finally {\r
+                       tt.done();\r
+               }\r
+               if(!opened) {\r
+                       throw new IOException("DataFile pair for " + name + " was not able to be opened in " + timeout + "ms");\r
+               }\r
+       }\r
+       \r
+       private synchronized void ensureIdxGood(AuthzTrans trans) throws IOException {\r
+               if(!idxf.exists() || idxf.length()==0 || dataf.lastModified()>idxf.lastModified()) {\r
+                       trans.warn().log(idxf.getCanonicalPath(),"is missing, empty or out of date, creating");\r
+                       RandomAccessFile raf = new RandomAccessFile(lockf, "rw");\r
+                       try {\r
+                               ti.create(trans, data, maxLineSize, delim, fieldOffset, skipLines);\r
+                               if(!idxf.exists() || (idxf.length()==0 && dataf.length()!=0)) {\r
+                                       throw new IOException("Data Index File did not create correctly");\r
+                               }\r
+                       } finally {\r
+                               raf.close();\r
+                               lockf.delete();\r
+                       }\r
+               }\r
+       }\r
+\r
+       public void close(AuthzTrans trans) throws IOException {\r
+               ti.close();\r
+               data.close();\r
+       }\r
+       \r
+       public class Reuse {\r
+               private Token tokenData;\r
+               private Field fieldData;\r
+\r
+               private Reuse(int size,char delim) {\r
+                       tokenData = data.new Token(size);\r
+                       fieldData = getTokenData().new Field(delim);\r
+               }\r
+               \r
+               public void reset() {\r
+                       getFieldData().reset();\r
+               }\r
+\r
+               public void pos(int rec) {\r
+                       getFieldData().reset();\r
+                       getTokenData().pos(rec);\r
+               }\r
+\r
+               public String next() {\r
+                       return getFieldData().next();\r
+               }\r
+               \r
+               public String at(int field) {\r
+                       return getFieldData().at(field);\r
+               }\r
+\r
+               public String atToEnd(int field) {\r
+                       return getFieldData().atToEnd(field);\r
+               }\r
+\r
+               public Field getFieldData() {\r
+                       return fieldData;\r
+               }\r
+\r
+               public Token getTokenData() {\r
+                       return tokenData;\r
+               }\r
+\r
+       }\r
+       \r
+       public Reuse reuse() {\r
+               return new Reuse(maxLineSize,delim);\r
+       }\r
+\r
+       public Iter iterator() {\r
+               return new Iter();\r
+       }\r
+       \r
+       public class Iter implements Iterator<String> {\r
+               private Reuse reuse;\r
+               private org.onap.aaf.authz.local.TextIndex.Iter tii;\r
+\r
+               public Iter() {\r
+                       reuse = reuse();\r
+                       tii = ti.new Iter();\r
+               }\r
+\r
+               @Override\r
+               public boolean hasNext() {\r
+                       return tii.hasNext();\r
+               }\r
+\r
+               @Override\r
+               public String next() {\r
+                       reuse.reset();\r
+                       int rec = tii.next();\r
+                       reuse.pos(rec);\r
+                       return reuse.at(0);\r
+               }\r
+\r
+               @Override\r
+               public void remove() {\r
+                       // read only\r
+               }\r
+       }\r
+}\r