001/* 002 * SonarQube 003 * Copyright (C) 2009-2017 SonarSource SA 004 * mailto:info 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 java.net.URL; 023import java.time.Clock; 024import java.util.Date; 025import java.util.Map; 026import java.util.Properties; 027import java.util.TimeZone; 028import javax.annotation.CheckForNull; 029import org.apache.commons.lang.SystemUtils; 030import org.sonar.api.batch.ScannerSide; 031import org.sonar.api.ce.ComputeEngineSide; 032import org.sonar.api.server.ServerSide; 033 034/** 035 * Proxy over {@link java.lang.System}. It aims to improve testability of classes 036 * that interact with low-level system methods, for example : 037 * <br> 038 * <pre> 039 * public class MyClass { 040 * private final System2 system; 041 * 042 * public MyClass(System2 s) { 043 * this.system = s; 044 * } 045 * 046 * public long xxx() { 047 * return system.now(); 048 * } 049 * } 050 * 051 * {@literal @}Test 052 * public void should_return_xxx() { 053 * // using Mockito 054 * System2 system = mock(System2.class); 055 * long now = 123456789L; 056 * doReturn(now).when(system).now(); 057 * assertThat(new MyClass(system).xxx()).isEqualTo(now); 058 * } 059 * </pre> 060 * <br> 061 * Note that the name System2 was chosen to not conflict with {@link java.lang.System}. 062 * <br> 063 * An instance is available in IoC container since 4.3. 064 * 065 * Since 6.4 you can also inject {@link Clock} instead of {@link System2} if you are only interested by date/time operations 066 * 067 * @since 4.2 068 */ 069@ScannerSide 070@ServerSide 071@ComputeEngineSide 072public class System2 { 073 074 public static final System2 INSTANCE = new System2(); 075 076 /** 077 * Shortcut for {@link System#currentTimeMillis()} 078 * Since 6.4 you can also inject {@link Clock} instead of {@link System2} 079 */ 080 public long now() { 081 return System.currentTimeMillis(); 082 } 083 084 /** 085 * Shortcut for {@link System#getProperties()} 086 */ 087 public Properties properties() { 088 return System.getProperties(); 089 } 090 091 /** 092 * Shortcut for {@link System#getProperty(String)} 093 */ 094 @CheckForNull 095 public String property(String key) { 096 return System.getProperty(key); 097 } 098 099 /** 100 * Shortcut for {@code System{@link #setProperty(String, String)}} 101 * @since 6.4 102 */ 103 public System2 setProperty(String key, String value) { 104 System.setProperty(key, value); 105 return this; 106 } 107 108 /** 109 * Shortcut for {@link System#getenv()} 110 */ 111 public Map<String, String> envVariables() { 112 return System.getenv(); 113 } 114 115 /** 116 * Shortcut for {@link System#getenv(String)} 117 */ 118 @CheckForNull 119 public String envVariable(String key) { 120 return System.getenv(key); 121 } 122 123 /** 124 * True if this is MS Windows. 125 */ 126 public boolean isOsWindows() { 127 return SystemUtils.IS_OS_WINDOWS; 128 } 129 130 /** 131 * True if Java 7 or Java 8 runtime environment 132 * @since 4.3 133 * @deprecated in 6.4. Java 8+ is required, so this method always returns {@code true}. 134 */ 135 @Deprecated 136 public boolean isJavaAtLeast17() { 137 return true; 138 } 139 140 public void println(String obj) { 141 System.out.print(obj); 142 } 143 144 /** 145 * @deprecated in 5.2. Please use {@link #now()} 146 */ 147 @Deprecated 148 public Date newDate() { 149 return new Date(); 150 } 151 152 /** 153 * @since 5.1 154 * @return the JVM's default time zone 155 */ 156 public TimeZone getDefaultTimeZone() { 157 return TimeZone.getDefault(); 158 } 159 160 /** 161 * @since 5.5 162 * @see Class#getResource(String) 163 */ 164 public URL getResource(String name) { 165 return getClass().getResource(name); 166 } 167 168 /** 169 * Closes the object and throws an {@link java.lang.IllegalStateException} on error. 170 * @since 5.1 171 */ 172 public void close(AutoCloseable closeable) { 173 try { 174 closeable.close(); 175 } catch (Exception e) { 176 throw new IllegalStateException("Fail to close " + closeable, e); 177 } 178 } 179}