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 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.BatchSide;
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@BatchSide
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 {@link System#getenv()}
097   */
098  public Map<String, String> envVariables() {
099    return System.getenv();
100  }
101
102  /**
103   * Shortcut for {@link System#getenv(String)}
104   */
105  @CheckForNull
106  public String envVariable(String key) {
107    return System.getenv(key);
108  }
109
110  /**
111   * True if this is MS Windows.
112   */
113  public boolean isOsWindows() {
114    return SystemUtils.IS_OS_WINDOWS;
115  }
116
117  /**
118   * True if Java 7 or Java 8 runtime environment
119   * @since 4.3
120   */
121  public boolean isJavaAtLeast17() {
122    return SystemUtils.isJavaVersionAtLeast(1.7f);
123  }
124
125  public void println(String obj) {
126    System.out.print(obj);
127  }
128
129  /**
130   * @deprecated in 5.2. Please use {@link #now()}
131   */
132  @Deprecated
133  public Date newDate() {
134    return new Date();
135  }
136
137  /**
138   * @since 5.1
139   * @return the JVM's default time zone
140   */
141  public TimeZone getDefaultTimeZone() {
142    return TimeZone.getDefault();
143  }
144
145  /**
146   * @since 5.5
147   * @see Class#getResource(String)
148   */
149  public URL getResource(String name) {
150    return getClass().getResource(name);
151  }
152
153  /**
154   * Closes the object and throws an {@link java.lang.IllegalStateException} on error.
155   * @since 5.1
156   */
157  public void close(AutoCloseable closeable) {
158    try {
159      closeable.close();
160    } catch (Exception e) {
161      throw new IllegalStateException("Fail to close " + closeable, e);
162    }
163  }
164}