001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: FuncSystemProperty.java 1225414 2011-12-29 02:38:30Z mrglavas $
020     */
021    package org.apache.xpath.functions;
022    
023    import java.io.BufferedInputStream;
024    import java.io.InputStream;
025    import java.util.Properties;
026    
027    import org.apache.xpath.XPathContext;
028    import org.apache.xpath.objects.XObject;
029    import org.apache.xpath.objects.XString;
030    import org.apache.xpath.res.XPATHErrorResources;
031    
032    /**
033     * Execute the SystemProperty() function.
034     * @xsl.usage advanced
035     */
036    public class FuncSystemProperty extends FunctionOneArg
037    {
038        static final long serialVersionUID = 3694874980992204867L;
039      /**
040       * The path/filename of the property file: XSLTInfo.properties
041       * Maintenance note: see also
042       * org.apache.xalan.processor.TransformerFactoryImpl.XSLT_PROPERTIES
043       */
044      static final String XSLT_PROPERTIES = 
045                "org/apache/xalan/res/XSLTInfo.properties";
046    
047      /**
048       * Execute the function.  The function must return
049       * a valid object.
050       * @param xctxt The current execution context.
051       * @return A valid XObject.
052       *
053       * @throws javax.xml.transform.TransformerException
054       */
055      public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
056      {
057    
058        String fullName = m_arg0.execute(xctxt).str();
059        int indexOfNSSep = fullName.indexOf(':');
060        String result;
061        String propName = "";
062    
063        // List of properties where the name of the
064        // property argument is to be looked for.
065        Properties xsltInfo = new Properties();
066    
067        loadPropertyFile(XSLT_PROPERTIES, xsltInfo);
068    
069        if (indexOfNSSep > 0)
070        {
071          String prefix = (indexOfNSSep >= 0)
072                          ? fullName.substring(0, indexOfNSSep) : "";
073          String namespace;
074    
075          namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
076          propName = (indexOfNSSep < 0)
077                     ? fullName : fullName.substring(indexOfNSSep + 1);
078    
079          if (namespace.startsWith("http://www.w3.org/XSL/Transform")
080                  || namespace.equals("http://www.w3.org/1999/XSL/Transform"))
081          {
082            result = xsltInfo.getProperty(propName);
083    
084            if (null == result)
085            {
086              warn(xctxt, XPATHErrorResources.WG_PROPERTY_NOT_SUPPORTED,
087                   new Object[]{ fullName });  //"XSL Property not supported: "+fullName);
088    
089              return XString.EMPTYSTRING;
090            }
091          }
092          else
093          {
094            warn(xctxt, XPATHErrorResources.WG_DONT_DO_ANYTHING_WITH_NS,
095                 new Object[]{ namespace,
096                               fullName });  //"Don't currently do anything with namespace "+namespace+" in property: "+fullName);
097    
098            try
099            {
100              result = System.getProperty(propName);
101    
102              if (null == result)
103              {
104    
105                // result = System.getenv(propName);
106                return XString.EMPTYSTRING;
107              }
108            }
109            catch (SecurityException se)
110            {
111              warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
112                   new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
113    
114              return XString.EMPTYSTRING;
115            }
116          }
117        }
118        else
119        {
120          try
121          {
122            result = System.getProperty(fullName);
123    
124            if (null == result)
125            {
126    
127              // result = System.getenv(fullName);
128              return XString.EMPTYSTRING;
129            }
130          }
131          catch (SecurityException se)
132          {
133            warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
134                 new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
135    
136            return XString.EMPTYSTRING;
137          }
138        }
139    
140        if (propName.equals("version") && result.length() > 0)
141        {
142          try
143          {
144            // Needs to return the version number of the spec we conform to.
145            return new XString("1.0");
146          }
147          catch (Exception ex)
148          {
149            return new XString(result);
150          }
151        }
152        else
153          return new XString(result);
154      }
155    
156      /**
157       * Retrieve a propery bundle from a specified file
158       * 
159       * @param file The string name of the property file.  The name 
160       * should already be fully qualified as path/filename
161       * @param target The target property bag the file will be placed into.
162       */
163      public void loadPropertyFile(String file, Properties target)
164      {
165        try
166        {
167          // Use SecuritySupport class to provide privileged access to property file
168          InputStream is = SecuritySupport.getResourceAsStream(ObjectFactory.findClassLoader(),
169                                                  file);
170    
171          // get a buffered version
172          BufferedInputStream bis = new BufferedInputStream(is);
173    
174          target.load(bis);  // and load up the property bag from this
175          bis.close();  // close out after reading
176        }
177        catch (Exception ex)
178        {
179          // ex.printStackTrace();
180          throw new org.apache.xml.utils.WrappedRuntimeException(ex);
181        }
182      }
183    }