Changeset eaac4d3


Ignore:
Timestamp:
Apr 27, 2015 3:41:38 PM (5 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
2750681
Parents:
f243968
Message:

NamingService?: Add export methods,
fill in subclass methods for efficient exporting,
fill in getBase64Entires() and getNames() where unimplemented
SusiDNS: Add export support, no UI yet

Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • apps/susidns/src/WEB-INF/web-template.xml

    rf243968 reaac4d3  
    4343    </servlet-mapping>
    4444
     45    <servlet-mapping>
     46        <servlet-name>i2p.susi.dns.jsp.export_jsp</servlet-name>
     47        <url-pattern>/export</url-pattern>
     48    </servlet-mapping>
     49
    4550    <session-config>
    4651        <session-timeout>
  • apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java

    rf243968 reaac4d3  
    2222package i2p.susi.dns;
    2323
     24import java.io.IOException;
     25import java.io.Writer;
    2426import java.util.Arrays;
    2527import java.util.LinkedList;
     
    2830import java.util.Map;
    2931import java.util.Properties;
     32import java.util.SortedMap;
    3033
    3134import net.i2p.client.naming.NamingService;
     
    197200                        }
    198201                        AddressBean array[] = list.toArray(new AddressBean[list.size()]);
    199                         Arrays.sort( array, sorter );
     202                        if (!(results instanceof SortedMap))
     203                            Arrays.sort( array, sorter );
    200204                        entries = array;
    201205
     
    352356                return rv;
    353357        }
     358
     359        /**
     360         *  @since 0.9.20
     361         */
     362        public void export(Writer out) throws IOException {
     363                Properties searchProps = new Properties();
     364                // only blockfile needs this
     365                searchProps.setProperty("list", getFileName());
     366                if (filter != null) {
     367                        String startsAt = filter.equals("0-9") ? "[0-9]" : filter;
     368                        searchProps.setProperty("startsWith", startsAt);
     369                }
     370                if (search != null && search.length() > 0)
     371                        searchProps.setProperty("search", search.toLowerCase(Locale.US));
     372                getNamingService().export(out, searchProps);
     373                // No post-filtering for hosts.txt naming services. It is what it is.
     374        }
    354375}
  • core/java/src/net/i2p/client/naming/BlockfileNamingService.java

    rf243968 reaac4d3  
    1919import java.util.Date;
    2020import java.util.HashMap;
     21import java.util.HashSet;
    2122import java.util.List;
    2223import java.util.Locale;
    2324import java.util.Map;
    2425import java.util.Properties;
     26import java.util.Set;
    2527import java.util.StringTokenizer;
     28import java.util.TreeMap;
    2629
    2730import net.i2p.I2PAppContext;
     
    861864                else
    862865                    iter = sl.iterator();
    863                 Map<String, Destination> rv = new HashMap<String, Destination>();
     866                Map<String, Destination> rv = new TreeMap<String, Destination>();
    864867                for (int i = 0; i < skip && iter.hasNext(); i++) {
    865868                    // don't bother validating here
     
    893896            } finally {
    894897                deleteInvalid();
     898            }
     899        }
     900    }
     901
     902    /**
     903     * @param options If non-null and contains the key "list", get
     904     *                from that list (default "hosts.txt", NOT all lists)
     905     *                Key "skip": skip that many entries
     906     *                Key "limit": max number to return
     907     *                Key "search": return only those matching substring
     908     *                Key "startsWith": return only those starting with
     909     *                                  ("[0-9]" allowed)
     910     *                Key "beginWith": start here in the iteration
     911     *                Don't use both startsWith and beginWith.
     912     *                Search, startsWith, and beginWith values must be lower case.
     913     *  @since 0.9.20
     914     */
     915    @Override
     916    public Map<String, String> getBase64Entries(Properties options) {
     917        String listname = FALLBACK_LIST;
     918        String search = null;
     919        String startsWith = null;
     920        String beginWith = null;
     921        int limit = Integer.MAX_VALUE;
     922        int skip = 0;
     923        if (options != null) {
     924            String ln = options.getProperty("list");
     925            if (ln != null)
     926                listname = ln;
     927            search = options.getProperty("search");
     928            startsWith = options.getProperty("startsWith");
     929            beginWith = options.getProperty("beginWith");
     930            if (beginWith == null && startsWith != null) {
     931                if (startsWith.equals("[0-9]"))
     932                    beginWith = "0";
     933                else
     934                    beginWith = startsWith;
     935            }
     936            String lim = options.getProperty("limit");
     937            try {
     938                limit = Integer.parseInt(lim);
     939            } catch (NumberFormatException nfe) {}
     940            String sk = options.getProperty("skip");
     941            try {
     942                skip = Integer.parseInt(sk);
     943            } catch (NumberFormatException nfe) {}
     944        }
     945        synchronized(_bf) {
     946            if (_isClosed)
     947                return Collections.emptyMap();
     948            try {
     949                SkipList sl = _bf.getIndex(listname, _stringSerializer, _destSerializer);
     950                if (sl == null) {
     951                    if (_log.shouldLog(Log.WARN))
     952                        _log.warn("No skiplist found for lookup in " + listname);
     953                    return Collections.emptyMap();
     954                }
     955                SkipIterator iter;
     956                if (beginWith != null)
     957                    iter = sl.find(beginWith);
     958                else
     959                    iter = sl.iterator();
     960                Map<String, String> rv = new TreeMap<String, String>();
     961                for (int i = 0; i < skip && iter.hasNext(); i++) {
     962                    // don't bother validating here
     963                    iter.next();
     964                }
     965                for (int i = 0; i < limit && iter.hasNext(); ) {
     966                    String key = (String) iter.nextKey();
     967                    if (startsWith != null) {
     968                        if (startsWith.equals("[0-9]")) {
     969                            if (key.charAt(0) > '9')
     970                                break;
     971                        } else if (!key.startsWith(startsWith)) {
     972                            break;
     973                        }
     974                    }
     975                    DestEntry de = (DestEntry) iter.next();
     976                    if (!validate(key, de, listname))
     977                        continue;
     978                    if (search != null && key.indexOf(search) < 0)
     979                        continue;
     980                    rv.put(key, de.dest.toBase64());
     981                    i++;
     982                }
     983                return rv;
     984            } catch (IOException ioe) {
     985                _log.error("DB lookup error", ioe);
     986                return Collections.emptyMap();
     987            } catch (RuntimeException re) {
     988                _log.error("DB lookup error", re);
     989                return Collections.emptyMap();
     990            } finally {
     991                deleteInvalid();
     992            }
     993        }
     994    }
     995
     996    /**
     997     * @param options If non-null and contains the key "list", get
     998     *                from that list (default "hosts.txt", NOT all lists)
     999     *                Key "skip": skip that many entries
     1000     *                Key "limit": max number to return
     1001     *                Key "search": return only those matching substring
     1002     *                Key "startsWith": return only those starting with
     1003     *                                  ("[0-9]" allowed)
     1004     *                Key "beginWith": start here in the iteration
     1005     *                Don't use both startsWith and beginWith.
     1006     *                Search, startsWith, and beginWith values must be lower case.
     1007     *  @since 0.9.20
     1008     */
     1009    @Override
     1010    public Set<String> getNames(Properties options) {
     1011        String listname = FALLBACK_LIST;
     1012        String search = null;
     1013        String startsWith = null;
     1014        String beginWith = null;
     1015        int limit = Integer.MAX_VALUE;
     1016        int skip = 0;
     1017        if (options != null) {
     1018            String ln = options.getProperty("list");
     1019            if (ln != null)
     1020                listname = ln;
     1021            search = options.getProperty("search");
     1022            startsWith = options.getProperty("startsWith");
     1023            beginWith = options.getProperty("beginWith");
     1024            if (beginWith == null && startsWith != null) {
     1025                if (startsWith.equals("[0-9]"))
     1026                    beginWith = "0";
     1027                else
     1028                    beginWith = startsWith;
     1029            }
     1030            String lim = options.getProperty("limit");
     1031            try {
     1032                limit = Integer.parseInt(lim);
     1033            } catch (NumberFormatException nfe) {}
     1034            String sk = options.getProperty("skip");
     1035            try {
     1036                skip = Integer.parseInt(sk);
     1037            } catch (NumberFormatException nfe) {}
     1038        }
     1039        synchronized(_bf) {
     1040            if (_isClosed)
     1041                return Collections.emptySet();
     1042            try {
     1043                SkipList sl = _bf.getIndex(listname, _stringSerializer, _destSerializer);
     1044                if (sl == null) {
     1045                    if (_log.shouldLog(Log.WARN))
     1046                        _log.warn("No skiplist found for lookup in " + listname);
     1047                    return Collections.emptySet();
     1048                }
     1049                SkipIterator iter;
     1050                if (beginWith != null)
     1051                    iter = sl.find(beginWith);
     1052                else
     1053                    iter = sl.iterator();
     1054                Set<String> rv = new HashSet<String>();
     1055                for (int i = 0; i < skip && iter.hasNext(); i++) {
     1056                    iter.next();
     1057                }
     1058                for (int i = 0; i < limit && iter.hasNext(); ) {
     1059                    String key = (String) iter.nextKey();
     1060                    if (startsWith != null) {
     1061                        if (startsWith.equals("[0-9]")) {
     1062                            if (key.charAt(0) > '9')
     1063                                break;
     1064                        } else if (!key.startsWith(startsWith)) {
     1065                            break;
     1066                        }
     1067                    }
     1068                    if (search != null && key.indexOf(search) < 0)
     1069                        continue;
     1070                    rv.add(key);
     1071                    i++;
     1072                }
     1073                return rv;
     1074            } catch (IOException ioe) {
     1075                _log.error("DB lookup error", ioe);
     1076                return Collections.emptySet();
     1077            } catch (RuntimeException re) {
     1078                _log.error("DB lookup error", re);
     1079                return Collections.emptySet();
    8951080            }
    8961081        }
  • core/java/src/net/i2p/client/naming/MetaNamingService.java

    rf243968 reaac4d3  
    11package net.i2p.client.naming;
    22
     3import java.io.IOException;
     4import java.io.Writer;
    35import java.lang.reflect.Constructor;
    46import java.util.Collections;
     
    182184    /**
    183185     *  All services aggregated
     186     *  @since 0.9.20
     187     */
     188    @Override
     189    public Map<String, String> getBase64Entries(Properties options) {
     190        Map<String, String> rv = new HashMap<String, String>();
     191        for (NamingService ns : _services) {
     192             rv.putAll(ns.getBase64Entries(options));
     193        }
     194        return rv;
     195    }
     196
     197    /**
     198     *  All services aggregated
    184199     */
    185200    @Override
     
    190205        }
    191206        return rv;
     207    }
     208
     209    /**
     210     *  All services aggregated.
     211     *  Duplicates not removed (for efficiency)
     212     *  @since 0.9.20
     213     */
     214    public void export(Writer out, Properties options) throws IOException {
     215        for (NamingService ns : _services) {
     216             export(out, options);
     217        }
    192218    }
    193219
  • core/java/src/net/i2p/client/naming/NamingService.java

    rf243968 reaac4d3  
    88package net.i2p.client.naming;
    99
     10import java.io.IOException;
     11import java.io.Writer;
    1012import java.lang.reflect.Constructor;
    1113import java.util.Collections;
     14import java.util.Date;
    1215import java.util.List;
    1316import java.util.Map;
    1417import java.util.Properties;
    1518import java.util.Set;
     19import java.util.TreeMap;
    1620import java.util.concurrent.CopyOnWriteArraySet;
    1721
     
    236240     *  if options is null, empty, or unsupported, use with caution.
    237241     *
     242     *  This implementation calls getEntries(options) and returns a SortedMap.
     243     *  Subclasses should override if they store base64 natively.
     244     *
    238245     *  @param options NamingService-specific, can be null
    239246     *  @return all mappings (matching the options if non-null)
    240247     *          or empty Map if none;
    241248     *          Returned Map is not necessarily sorted, implementation dependent
    242      *  @since 0.8.7
     249     *  @since 0.8.7, implemented in 0.9.20
    243250     */
    244251    public Map<String, String> getBase64Entries(Properties options) {
    245         return Collections.emptyMap();
     252        Map<String, Destination> entries = getEntries(options);
     253        if (entries.size() <= 0)
     254            return Collections.emptyMap();
     255        Map<String, String> rv = new TreeMap<String, String>();
     256        for (Map.Entry<String, Destination> e : entries.entrySet()) {
     257             rv.put(e.getKey(), e.getValue().toBase64());
     258        }
     259        return rv;
     260    }
     261
     262    /**
     263     *  Export in a hosts.txt format.
     264     *  Output is not necessarily sorted, implementation dependent.
     265     *  Output may or may not contain comment lines, implementation dependent.
     266     *  Caller must close writer.
     267     *
     268     *  This implementation calls getBase64Entries().
     269     *  Subclasses should override if they store in a hosts.txt format natively.
     270     *
     271     *  @since 0.9.20
     272     */
     273    public void export(Writer out) throws IOException {
     274        export(out, null);
     275    }
     276
     277    /**
     278     *  Export in a hosts.txt format.
     279     *  Output is not necessarily sorted, implementation dependent.
     280     *  Output may or may not contain comment lines, implementation dependent.
     281     *  Caller must close writer.
     282     *
     283     *  This implementation calls getBase64Entries(options).
     284     *  Subclasses should override if they store in a hosts.txt format natively.
     285     *
     286     *  @param options NamingService-specific, can be null
     287     *  @since 0.9.20
     288     */
     289    public void export(Writer out, Properties options) throws IOException {
     290        Map<String, String> entries = getBase64Entries(options);
     291        out.write("# Address book: ");
     292        out.write(getName());
     293        out.write('\n');
     294        int sz = entries.size();
     295        if (sz <= 0) {
     296            out.write("# No entries\n");
     297            return;
     298        }
     299        out.write("# Exported: ");
     300        out.write((new Date()).toString());
     301        out.write('\n');
     302        if (sz > 1) {
     303            out.write("# " + sz + " entries\n");
     304        }
     305        for (Map.Entry<String, String> e : entries.entrySet()) {
     306            out.write(e.getKey());
     307            out.write('=');
     308            out.write(e.getValue());
     309            out.write('\n');
     310        }
    246311    }
    247312
  • core/java/src/net/i2p/client/naming/SingleFileNamingService.java

    rf243968 reaac4d3  
    1616import java.io.OutputStream;
    1717import java.io.OutputStreamWriter;
     18import java.io.Writer;
    1819import java.util.Collections;
     20import java.util.Date;
    1921import java.util.HashMap;
    2022import java.util.HashSet;
     
    366368
    367369    /**
     370     *  Overridden since we store base64 natively.
     371     *
     372     *  @param options As follows:
     373     *                 Key "search": return only those matching substring
     374     *                 Key "startsWith": return only those starting with
     375     *                                   ("[0-9]" allowed)
     376     *  @return all mappings (matching the options if non-null)
     377     *          or empty Map if none.
     378     *          Returned Map is not sorted.
     379     *  @since 0.9.20
     380     */
     381    public Map<String, String> getBase64Entries(Properties options) {
     382        if (!_file.exists())
     383            return Collections.emptyMap();
     384        String searchOpt = null;
     385        String startsWith = null;
     386        if (options != null) {
     387            searchOpt = options.getProperty("search");
     388            startsWith = options.getProperty("startsWith");
     389        }
     390        BufferedReader in = null;
     391        getReadLock();
     392        try {
     393            in = new BufferedReader(new InputStreamReader(new FileInputStream(_file), "UTF-8"), 16*1024);
     394            String line = null;
     395            Map<String, String> rv = new HashMap<String, String>();
     396            while ( (line = in.readLine()) != null) {
     397                if (line.length() <= 0)
     398                    continue;
     399                if (startsWith != null) {
     400                    if (startsWith.equals("[0-9]")) {
     401                        if (line.charAt(0) < '0' || line.charAt(0) > '9')
     402                            continue;
     403                    } else if (!line.startsWith(startsWith)) {
     404                        continue;
     405                    }
     406                }
     407                if (line.startsWith("#"))
     408                    continue;
     409                if (line.indexOf('#') > 0)  // trim off any end of line comment
     410                    line = line.substring(0, line.indexOf('#')).trim();
     411                int split = line.indexOf('=');
     412                if (split <= 0)
     413                    continue;
     414                String key = line.substring(0, split);
     415                if (searchOpt != null && key.indexOf(searchOpt) < 0)
     416                    continue;
     417                String b64 = line.substring(split+1);   //.trim() ??????????????
     418                if (b64.length() < 387)
     419                    continue;
     420                rv.put(key, b64);
     421            }
     422            if (searchOpt == null && startsWith == null) {
     423                _lastWrite = _file.lastModified();
     424                _size = rv.size();
     425            }
     426            return rv;
     427        } catch (IOException ioe) {
     428            _log.error("getEntries error", ioe);
     429            return Collections.emptyMap();
     430        } finally {
     431            if (in != null) try { in.close(); } catch (IOException ioe) {}
     432            releaseReadLock();
     433        }
     434    }
     435
     436    /**
     437     *  Overridden for efficiency.
     438     *  Output is not sorted.
     439     *
     440     *  @param options ignored
     441     *  @since 0.9.20
     442     */
     443    public void export(Writer out, Properties options) throws IOException {
     444        out.write("# Address book: ");
     445        out.write(getName());
     446        out.write('\n');
     447        out.write("# Exported: ");
     448        out.write((new Date()).toString());
     449        out.write('\n');
     450        BufferedReader in = null;
     451        getReadLock();
     452        try {
     453            in = new BufferedReader(new InputStreamReader(new FileInputStream(_file), "UTF-8"), 16*1024);
     454            String line = null;
     455            while ( (line = in.readLine()) != null) {
     456                out.write(line);
     457                out.write('\n');
     458            }
     459        } finally {
     460            if (in != null) try { in.close(); } catch (IOException ioe) {}
     461            releaseReadLock();
     462        }
     463    }
     464
     465    /**
    368466     *  @param options ignored
    369467     *  @return all known host names, unsorted
Note: See TracChangeset for help on using the changeset viewer.