diff --git a/source/net/yacy/cora/storage/ConfigurationSet.java b/source/net/yacy/cora/storage/ConfigurationSet.java new file mode 100644 index 000000000..6ad6ce12e --- /dev/null +++ b/source/net/yacy/cora/storage/ConfigurationSet.java @@ -0,0 +1,261 @@ +/** + * ConfigurationSet + * Copyright 2011 by Michael Peter Christen, mc@yacy.net, Frankfurt a. M., Germany + * First released 29.06.2011 at http://yacy.net + * + * $LastChangedDate: 2011-05-30 10:53:58 +0200 (Mo, 30 Mai 2011) $ + * $LastChangedRevision: 7759 $ + * $LastChangedBy: orbiter $ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.cora.storage; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Set; + +/** + * this class reads configuration attributes as a list of keywords from a list + * the list may contain lines with one keyword, comment lines, empty lines and out-commented keyword lines + * when an attribute is changed here, the list is stored again with the original formatting + * + * @author Michael Christen + */ +public class ConfigurationSet extends AbstractSet implements Set { + + private final File file; + private String[] lines; + + public ConfigurationSet(final File file) { + this.file = file; + try { + final BufferedReader br = new BufferedReader(new FileReader(this.file)); + final LinkedList sl = new LinkedList(); + String s; + while ((s = br.readLine()) != null) sl.add(s.trim()); + this.lines = new String[sl.size()]; + int c = 0; + for (final String s0: sl) this.lines[c++] = s0; + } catch (final IOException e) { + this.lines = new String[0]; + } + } + + /** + * save the configuration back to the file + * @throws IOException + */ + private void commit() throws IOException { + final BufferedWriter writer = new BufferedWriter(new FileWriter(this.file)); + for (final String s: this.lines) { + writer.write(s); + writer.write("\n"); + } + writer.close(); + } + + @Override + public Iterator iterator() { + return new LineIterator(true); + } + + public Iterator disabledIterator() { + return new LineIterator(false); + } + + public Iterator allIterator() { + return new EntryIterator(); + } + + private boolean isCommentLine(final int line) { + return this.lines[line].startsWith("##"); + } + + private boolean isKeyLine(final int line) { + return this.lines[line].length() > 0 && this.lines[line].charAt(0) != '#'; + } + + private boolean isDisabledLine(final int line) { + return this.lines[line].length() > 1 && this.lines[line].charAt(0) == '#' && this.lines[line].charAt(1) != '#'; + } + + public void enable(final String key) throws IOException { + for (int i = 0; i < this.lines.length; i++) { + if (isDisabledLine(i) && this.lines[i].substring(1).trim().equals(key)) { + this.lines[i] = key; + commit(); + return; + } + } + } + + public void disable(final String key) throws IOException { + for (int i = 0; i < this.lines.length; i++) { + if (isKeyLine(i) && this.lines[i].equals(key)) { + this.lines[i] = "#" + key; + commit(); + return; + } + } + } + + public String commentHeadline(final String key) { + for (int i = 1; i < this.lines.length; i++) { + if (this.lines[i].equals(key) || + (isDisabledLine(i) && this.lines[i].substring(1).trim().equals(key)) + ) { + return isCommentLine(i - 1) ? this.lines[i - 1].substring(2).trim() : ""; + } + } + return ""; + } + + public class LineIterator implements Iterator { + + EntryIterator i; + Entry nextEntry; + private final boolean enabled; + + public LineIterator(final boolean enabled) { + this.enabled = enabled; + this.i = new EntryIterator(); + findNextValid(); + } + + public void findNextValid() { + while (this.i.hasNext()) { + this.nextEntry = this.i.next(); + if (this.nextEntry.enabled() == this.enabled) return; + } + this.nextEntry = null; + } + + @Override + public boolean hasNext() { + return this.nextEntry != null; + } + + @Override + public String next() { + if (this.nextEntry == null) return null; + final String s = this.nextEntry.key(); + findNextValid(); + return s; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + public class EntryIterator implements Iterator { + + private int line; + + public EntryIterator() { + this.line = -1; + findNextKeywordLine(); + } + + /** + * increase line counter until it points to the next keyword line + * @return true if a next line was found, false if EOL + */ + private boolean findNextKeywordLine() { + this.line++; + if (this.line >= ConfigurationSet.this.lines.length) return false; + while (ConfigurationSet.this.lines[this.line].length() == 0 || + ConfigurationSet.this.lines[this.line].startsWith("##")) { + this.line++; + if (this.line >= ConfigurationSet.this.lines.length) return false; + } + return true; + } + + @Override + public boolean hasNext() { + return this.line < ConfigurationSet.this.lines.length; + } + + @Override + public Entry next() { + final String s = ConfigurationSet.this.lines[this.line]; + findNextKeywordLine(); + if (s.charAt(0) == '#') return new Entry(s.substring(1).trim(), false); + return new Entry(s, true); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + public class Entry { + private final String key; + private final boolean enabled; + public Entry(final String key, final boolean enabled) { + this.enabled = enabled; + this.key = key; + } + public String key() { + return this.key; + } + public boolean enabled() { + return this.enabled; + } + } + + @Override + public int size() { + int c = 0; + for (final String s: this.lines) { + if (s.length() > 0 && s.charAt(0) != '#') c++; + } + return c; + } + + public static void main(final String[] args) { + if (args.length == 0) return; + final File f = new File(args[0]); + final ConfigurationSet cs = new ConfigurationSet(f); + Iterator i = cs.iterator(); + String k; + System.out.println("\nall activated attributes:"); + while (i.hasNext()) { + k = i.next(); + System.out.println(k + " - " + cs.commentHeadline(k)); + } + i = cs.disabledIterator(); + System.out.println("\nall deactivated attributes:"); + while (i.hasNext()) { + k = i.next(); + System.out.println(k + " - " + cs.commentHeadline(k)); + } + } + +}