001/* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2013 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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.BatchComponent; 029import org.sonar.api.ServerComponent; 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 */ 044public class UriReader implements BatchComponent, ServerComponent { 045 046 private final Map<String, SchemeProcessor> processorsByScheme = Maps.newHashMap(); 047 048 public UriReader(SchemeProcessor[] processors) { 049 List<SchemeProcessor> allProcessors = Lists.asList(new FileProcessor(), processors); 050 for (SchemeProcessor processor : allProcessors) { 051 for (String scheme : processor.getSupportedSchemes()) { 052 processorsByScheme.put(scheme.toLowerCase(Locale.ENGLISH), processor); 053 } 054 } 055 } 056 057 /** 058 * Reads all bytes from uri. It throws an unchecked exception if an error occurs. 059 */ 060 public byte[] readBytes(URI uri) { 061 return searchForSupportedProcessor(uri).readBytes(uri); 062 } 063 064 /** 065 * Reads all characters from uri, using the given character set. 066 * It throws an unchecked exception if an error occurs. 067 */ 068 public String readString(URI uri, Charset charset) { 069 return searchForSupportedProcessor(uri).readString(uri, charset); 070 } 071 072 /** 073 * Returns a detailed description of the given uri. For example HTTP URIs are completed 074 * with the configured HTTP proxy. 075 */ 076 public String description(URI uri) { 077 SchemeProcessor reader = searchForSupportedProcessor(uri); 078 079 return reader.description(uri); 080 } 081 082 @VisibleForTesting 083 SchemeProcessor searchForSupportedProcessor(URI uri) { 084 SchemeProcessor processor = processorsByScheme.get(uri.getScheme().toLowerCase(Locale.ENGLISH)); 085 Preconditions.checkArgument(processor != null, "URI schema is not supported: " + uri.getScheme()); 086 return processor; 087 } 088 089 abstract static class SchemeProcessor { 090 abstract String[] getSupportedSchemes(); 091 092 abstract byte[] readBytes(URI uri); 093 094 abstract String readString(URI uri, Charset charset); 095 096 abstract String description(URI uri); 097 } 098 099 100 /** 101 * This implementation is not exposed in API and is kept private. 102 */ 103 private static class FileProcessor extends SchemeProcessor { 104 105 @Override 106 public String[] getSupportedSchemes() { 107 return new String[]{"file"}; 108 } 109 110 @Override 111 byte[] readBytes(URI uri) { 112 try { 113 return Files.toByteArray(new File(uri)); 114 } catch (IOException e) { 115 throw Throwables.propagate(e); 116 } 117 } 118 119 @Override 120 String readString(URI uri, Charset charset) { 121 try { 122 return Files.toString(new File(uri), charset); 123 } catch (IOException e) { 124 throw Throwables.propagate(e); 125 } 126 } 127 128 @Override 129 String description(URI uri) { 130 return new File(uri).getAbsolutePath(); 131 } 132 } 133}