Java tutorial
/* * Copyright (c) 2009 - 2015 Deutsches Elektronen-Synchroton, * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 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 Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this program (see the file COPYING.LIB for more * details); if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.dcache.nfs; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; import java.util.Iterator; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Ordering; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ExportFile { private static final Logger _log = LoggerFactory.getLogger(ExportFile.class); private volatile ImmutableMultimap<Integer, FsExport> _exports; private final URI _exportFile; public ExportFile(File file) throws IOException { this(file.toURI()); } public ExportFile(URI uri) throws IOException { _exportFile = uri; _exports = parse(_exportFile); } public Iterable<FsExport> getExports() { return _exports.values(); } private static ImmutableMultimap<Integer, FsExport> parse(URI exportFile) throws IOException { ImmutableListMultimap.Builder<Integer, FsExport> exportsBuilder = ImmutableListMultimap.builder(); for (String line : Files.readAllLines(Paths.get(exportFile))) { line = line.trim(); if (line.length() == 0) { continue; } if (line.charAt(0) == '#') { continue; } if (line.charAt(0) != '/') { _log.warn("Ignoring entry with non absolute export path: " + line); continue; } int pathEnd = line.indexOf(' '); String path; if (pathEnd < 0) { FsExport export = new FsExport.FsExportBuilder().build(line); exportsBuilder.put(export.getIndex(), export); continue; } else { path = line.substring(0, pathEnd); } Splitter splitter = Splitter.on(' ').omitEmptyStrings().trimResults(); for (String hostAndOptions : splitter.split(line.substring(pathEnd + 1))) { try { FsExport.FsExportBuilder exportBuilder = new FsExport.FsExportBuilder(); Iterator<String> s = Splitter.on(CharMatcher.anyOf("(,)")).omitEmptyStrings().trimResults() .split(hostAndOptions).iterator(); String host = s.next(); exportBuilder.forClient(host); while (s.hasNext()) { String option = s.next(); if (option.equals("rw")) { exportBuilder.rw(); continue; } if (option.equals("ro")) { exportBuilder.ro(); continue; } if (option.equals("root_squash")) { exportBuilder.notTrusted(); continue; } if (option.equals("no_root_squash")) { exportBuilder.trusted(); continue; } if (option.equals("acl")) { exportBuilder.withAcl(); continue; } if (option.equals("noacl") || option.equals("no_acl")) { exportBuilder.withoutAcl(); continue; } if (option.equals("all_squash")) { exportBuilder.allSquash(); continue; } if (option.startsWith("sec=")) { String secFlavor = option.substring(4); exportBuilder.withSec(FsExport.Sec.valueOf(secFlavor.toUpperCase())); continue; } if (option.startsWith("anonuid=")) { int anonuid = Integer.parseInt(option.substring(8)); exportBuilder.withAnonUid(anonuid); continue; } if (option.startsWith("anongid=")) { int anongid = Integer.parseInt(option.substring(8)); exportBuilder.withAnonGid(anongid); continue; } if (option.equals("dcap")) { exportBuilder.withDcap(); continue; } if (option.equals("no_dcap")) { exportBuilder.withoutDcap(); continue; } if (option.equals("all_root")) { exportBuilder.withAllRoot(); continue; } if (option.equals("pnfs")) { exportBuilder.withPnfs(); continue; } if (option.equals("nopnfs") || option.equals("no_pnfs")) { exportBuilder.withoutPnfs(); continue; } throw new IllegalArgumentException("Unsupported option: " + option); } FsExport export = exportBuilder.build(path); exportsBuilder.put(export.getIndex(), export); } catch (IllegalArgumentException e) { _log.error("Invalid export entry [" + hostAndOptions + "] : " + e.getMessage()); } } } /* * sort in reverse order to get smallest network first */ return exportsBuilder .orderValuesBy(Ordering.from(HostEntryComparator::compare).onResultOf(FsExport::client).reverse()) .build(); } public FsExport getExport(String path, InetAddress client) { String normalizedPath = FsExport.normalize(path); return getExport(FsExport.getExportIndex(normalizedPath), client); } public FsExport getExport(int index, InetAddress client) { for (FsExport export : _exports.get(index)) { if (export.isAllowed(client)) { return export; } } return null; } public Stream<FsExport> exportsFor(InetAddress client) { return _exports.values().stream().filter(e -> e.isAllowed(client)); } public void rescan() throws IOException { _exports = parse(_exportFile); } }