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 java.io.File; 029import java.io.IOException; 030import java.net.URI; 031import java.nio.charset.Charset; 032import java.util.List; 033import java.util.Locale; 034import java.util.Map; 035import org.sonar.api.batch.ScannerSide; 036import org.sonar.api.ce.ComputeEngineSide; 037import org.sonar.api.server.ServerSide; 038 039/** 040 * Reads different types of URI. Supported schemes are http and file. 041 * 042 * @since 3.2 043 */ 044@ScannerSide 045@ServerSide 046@ComputeEngineSide 047public class UriReader { 048 049 private final Map<String, SchemeProcessor> processorsByScheme = Maps.newHashMap(); 050 051 public UriReader(SchemeProcessor[] processors) { 052 List<SchemeProcessor> allProcessors = Lists.asList(new FileProcessor(), processors); 053 for (SchemeProcessor processor : allProcessors) { 054 for (String scheme : processor.getSupportedSchemes()) { 055 processorsByScheme.put(scheme.toLowerCase(Locale.ENGLISH), processor); 056 } 057 } 058 } 059 060 /** 061 * Reads all bytes from uri. It throws an unchecked exception if an error occurs. 062 */ 063 public byte[] readBytes(URI uri) { 064 return searchForSupportedProcessor(uri).readBytes(uri); 065 } 066 067 /** 068 * Reads all characters from uri, using the given character set. 069 * It throws an unchecked exception if an error occurs. 070 */ 071 public String readString(URI uri, Charset charset) { 072 return searchForSupportedProcessor(uri).readString(uri, charset); 073 } 074 075 /** 076 * Returns a detailed description of the given uri. For example HTTP URIs are completed 077 * with the configured HTTP proxy. 078 */ 079 public String description(URI uri) { 080 SchemeProcessor reader = searchForSupportedProcessor(uri); 081 082 return reader.description(uri); 083 } 084 085 @VisibleForTesting 086 SchemeProcessor searchForSupportedProcessor(URI uri) { 087 SchemeProcessor processor = processorsByScheme.get(uri.getScheme().toLowerCase(Locale.ENGLISH)); 088 Preconditions.checkArgument(processor != null, "URI schema is not supported: " + uri.getScheme()); 089 return processor; 090 } 091 092 public abstract static class SchemeProcessor { 093 protected abstract String[] getSupportedSchemes(); 094 095 protected abstract byte[] readBytes(URI uri); 096 097 protected abstract String readString(URI uri, Charset charset); 098 099 protected abstract String description(URI uri); 100 } 101 102 /** 103 * This implementation is not exposed in API and is kept private. 104 */ 105 private static class FileProcessor extends SchemeProcessor { 106 107 @Override 108 public String[] getSupportedSchemes() { 109 return new String[] {"file"}; 110 } 111 112 @Override 113 protected byte[] readBytes(URI uri) { 114 try { 115 return Files.toByteArray(new File(uri)); 116 } catch (IOException e) { 117 throw Throwables.propagate(e); 118 } 119 } 120 121 @Override 122 protected String readString(URI uri, Charset charset) { 123 try { 124 return Files.toString(new File(uri), charset); 125 } catch (IOException e) { 126 throw Throwables.propagate(e); 127 } 128 } 129 130 @Override 131 protected String description(URI uri) { 132 return new File(uri).getAbsolutePath(); 133 } 134 } 135}