001/* 002 * SonarQube 003 * Copyright (C) 2009-2016 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020package org.sonar.api.utils; 021 022import com.google.common.annotations.VisibleForTesting; 023import com.google.common.base.Preconditions; 024import com.google.common.base.Throwables; 025import com.google.common.collect.Lists; 026import com.google.common.collect.Maps; 027import com.google.common.io.Files; 028import org.sonar.api.batch.BatchSide; 029import org.sonar.api.server.ServerSide; 030 031import java.io.File; 032import java.io.IOException; 033import java.net.URI; 034import java.nio.charset.Charset; 035import java.util.List; 036import java.util.Locale; 037import java.util.Map; 038 039/** 040 * Reads different types of URI. Supported schemes are http and file. 041 * 042 * @since 3.2 043 */ 044@BatchSide 045@ServerSide 046public class UriReader { 047 048 private final Map<String, SchemeProcessor> processorsByScheme = Maps.newHashMap(); 049 050 public UriReader(SchemeProcessor[] processors) { 051 List<SchemeProcessor> allProcessors = Lists.asList(new FileProcessor(), processors); 052 for (SchemeProcessor processor : allProcessors) { 053 for (String scheme : processor.getSupportedSchemes()) { 054 processorsByScheme.put(scheme.toLowerCase(Locale.ENGLISH), processor); 055 } 056 } 057 } 058 059 /** 060 * Reads all bytes from uri. It throws an unchecked exception if an error occurs. 061 */ 062 public byte[] readBytes(URI uri) { 063 return searchForSupportedProcessor(uri).readBytes(uri); 064 } 065 066 /** 067 * Reads all characters from uri, using the given character set. 068 * It throws an unchecked exception if an error occurs. 069 */ 070 public String readString(URI uri, Charset charset) { 071 return searchForSupportedProcessor(uri).readString(uri, charset); 072 } 073 074 /** 075 * Returns a detailed description of the given uri. For example HTTP URIs are completed 076 * with the configured HTTP proxy. 077 */ 078 public String description(URI uri) { 079 SchemeProcessor reader = searchForSupportedProcessor(uri); 080 081 return reader.description(uri); 082 } 083 084 @VisibleForTesting 085 SchemeProcessor searchForSupportedProcessor(URI uri) { 086 SchemeProcessor processor = processorsByScheme.get(uri.getScheme().toLowerCase(Locale.ENGLISH)); 087 Preconditions.checkArgument(processor != null, "URI schema is not supported: " + uri.getScheme()); 088 return processor; 089 } 090 091 public abstract static class SchemeProcessor { 092 protected abstract String[] getSupportedSchemes(); 093 094 protected abstract byte[] readBytes(URI uri); 095 096 protected abstract String readString(URI uri, Charset charset); 097 098 protected abstract String description(URI uri); 099 } 100 101 /** 102 * This implementation is not exposed in API and is kept private. 103 */ 104 private static class FileProcessor extends SchemeProcessor { 105 106 @Override 107 public String[] getSupportedSchemes() { 108 return new String[] {"file"}; 109 } 110 111 @Override 112 protected byte[] readBytes(URI uri) { 113 try { 114 return Files.toByteArray(new File(uri)); 115 } catch (IOException e) { 116 throw Throwables.propagate(e); 117 } 118 } 119 120 @Override 121 protected String readString(URI uri, Charset charset) { 122 try { 123 return Files.toString(new File(uri), charset); 124 } catch (IOException e) { 125 throw Throwables.propagate(e); 126 } 127 } 128 129 @Override 130 protected String description(URI uri) { 131 return new File(uri).getAbsolutePath(); 132 } 133 } 134}