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