001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 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 org.apache.commons.lang.SystemUtils;
023import org.sonar.api.BatchComponent;
024import org.sonar.api.ServerComponent;
025
026import javax.annotation.CheckForNull;
027
028import java.util.Date;
029import java.util.Map;
030import java.util.Properties;
031import java.util.TimeZone;
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 * <p/>
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 * <p/>
060 * Note that the name System2 was chosen to not conflict with {@link java.lang.System}.
061 * <p/>
062 * An instance is available in IoC container since 4.3.
063 *
064 * @since 4.2
065 */
066public class System2 implements BatchComponent, ServerComponent {
067
068  public static final System2 INSTANCE = new System2();
069
070  /**
071   * Shortcut for {@link System#currentTimeMillis()}
072   */
073  public long now() {
074    return System.currentTimeMillis();
075  }
076
077  /**
078   * Shortcut for {@link System#getProperties()}
079   */
080  public Properties properties() {
081    return System.getProperties();
082  }
083
084  /**
085   * Shortcut for {@link System#getProperty(String)}
086   */
087  @CheckForNull
088  public String property(String key) {
089    return System.getProperty(key);
090  }
091
092  /**
093   * Shortcut for {@link System#getenv()}
094   */
095  public Map<String, String> envVariables() {
096    return System.getenv();
097  }
098
099  /**
100   * Shortcut for {@link System#getenv(String)}
101   */
102  @CheckForNull
103  public String envVariable(String key) {
104    return System.getenv(key);
105  }
106
107  /**
108   * True if this is MS Windows.
109   */
110  public boolean isOsWindows() {
111    return SystemUtils.IS_OS_WINDOWS;
112  }
113
114  /**
115   * True if Java 7 or Java 8 runtime environment
116   * @since 4.3
117   */
118  public boolean isJavaAtLeast17() {
119    return SystemUtils.isJavaVersionAtLeast(1.7f);
120  }
121
122  public void println(String obj) {
123    System.out.print(obj);
124  }
125
126  public Date newDate() {
127    return new Date();
128  }
129
130  /**
131   * @since 5.1
132   * @return the JVM's default time zone
133   */
134  public TimeZone getDefaultTimeZone() {
135    return TimeZone.getDefault();
136  }
137
138  /**
139   * Closes the object and throws an {@link java.lang.IllegalStateException} on error.
140   * @since 5.1
141   */
142  public void close(AutoCloseable closeable) {
143    try {
144      closeable.close();
145    } catch (Exception e) {
146      throw new IllegalStateException("Fail to close " + closeable, e);
147    }
148  }
149}