001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.commons.svl.vars;
018
019import org.apache.juneau.commons.settings.*;
020import org.apache.juneau.commons.svl.*;
021
022/**
023 * System property variable resolver.
024 *
025 * <p>
026 * The format for this var is <js>"$S{systemProperty[,defaultValue]}"</js>
027 *
028 * <h5 class='section'>Example:</h5>
029 * <p class='bjava'>
030 *    <jc>// Create a variable resolver that resolves system properties (e.g. "$S{java.home}")</jc>
031 *    VarResolver <jv>varResolver</jv> = VarResolver.<jsm>create</jsm>().vars(SystemPropertiesVar.<jk>class</jk>).build();
032 *
033 *    <jc>// Use it!</jc>
034 *    System.<jsf>out</jsf>.println(<jv>varResolver</jv>.resolve(<js>"java.home is set to $S{java.home}"</js>));
035 * </p>
036 *
037 * <p>
038 * Since this is a {@link SimpleVar}, any variables contained in the result will be recursively resolved.
039 * <br>Likewise, if the arguments contain any variables, those will be resolved before they are passed to this var.
040 *
041 * <h5 class='section'>See Also:</h5><ul>
042 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MarshallSimpleVariableLanguage">Marshall Simple Variable Language</a>
043 * </ul>
044 */
045public class SystemPropertiesVar extends DefaultingVar {
046   private final SystemPropertyPropertySource source = new SystemPropertyPropertySource();
047
048
049   /** The name of this variable. */
050   public static final String NAME = "S";
051
052   /**
053    * Constructor.
054    */
055   public SystemPropertiesVar() {
056      super(NAME);
057   }
058
059   @Override /* Overridden from Var */
060   public String resolve(VarResolverSession session, String key) {
061      var v = source.get(key);
062      return v.isPresent() ? v.value().orElse(null) : null;
063   }
064
065   /**
066    * System properties are mutable in principle (via {@link System#setProperty}) but treated
067    * as stable in normal application code. This var opts in to compile-time stable-value
068    * folding.
069    *
070    * <h5 class='section'>Caveat:</h5>
071    * <p>
072    * If a deployment relies on {@link System#setProperty} mutations <i>after</i>
073    * {@link VarResolver} build, those mutations will <b>not</b> be picked up by templates
074    * that were compiled before the mutation. Either re-build the resolver after the property
075    * change, or override this method to return {@code false} via a subclass.
076    *
077    * @return Always {@code true} for the default implementation.
078    */
079   @Override /* Overridden from Var */
080   protected boolean isStable() {
081      return true;
082   }
083}