1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the  "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 /*
19  * $Id: FuncSystemProperty.java 468655 2006-10-28 07:12:06Z minchau $
20  */
21 package org.apache.xpath.functions;
22 
23 import java.io.BufferedInputStream;
24 import java.io.InputStream;
25 import java.util.Properties;
26 
27 import org.apache.xpath.XPathContext;
28 import org.apache.xpath.objects.XNumber;
29 import org.apache.xpath.objects.XObject;
30 import org.apache.xpath.objects.XString;
31 import org.apache.xpath.res.XPATHErrorResources;
32 
33 /**
34  * Execute the SystemProperty() function.
35  * @xsl.usage advanced
36  */
37 public class FuncSystemProperty extends FunctionOneArg
38 {
39     static final long serialVersionUID = 3694874980992204867L;
40   /**
41    * The path/filename of the property file: XSLTInfo.properties
42    * Maintenance note: see also
43    * org.apache.xalan.processor.TransformerFactoryImpl.XSLT_PROPERTIES
44    */
45   static final String XSLT_PROPERTIES =
46             "org/apache/xalan/res/XSLTInfo.properties";
47 
48   /**
49    * Execute the function.  The function must return
50    * a valid object.
51    * @param xctxt The current execution context.
52    * @return A valid XObject.
53    *
54    * @throws javax.xml.transform.TransformerException
55    */
execute(XPathContext xctxt)56   public XObject execute(XPathContext xctxt) throws javax.xml.transform.TransformerException
57   {
58 
59     String fullName = m_arg0.execute(xctxt).str();
60     int indexOfNSSep = fullName.indexOf(':');
61     String result = null;
62     String propName = "";
63 
64     // List of properties where the name of the
65     // property argument is to be looked for.
66     Properties xsltInfo = new Properties();
67 
68     loadPropertyFile(XSLT_PROPERTIES, xsltInfo);
69 
70     if (indexOfNSSep > 0)
71     {
72       String prefix = (indexOfNSSep >= 0)
73                       ? fullName.substring(0, indexOfNSSep) : "";
74       String namespace;
75 
76       namespace = xctxt.getNamespaceContext().getNamespaceForPrefix(prefix);
77       propName = (indexOfNSSep < 0)
78                  ? fullName : fullName.substring(indexOfNSSep + 1);
79 
80       if (namespace.startsWith("http://www.w3.org/XSL/Transform")
81               || namespace.equals("http://www.w3.org/1999/XSL/Transform"))
82       {
83         result = xsltInfo.getProperty(propName);
84 
85         if (null == result)
86         {
87           warn(xctxt, XPATHErrorResources.WG_PROPERTY_NOT_SUPPORTED,
88                new Object[]{ fullName });  //"XSL Property not supported: "+fullName);
89 
90           return XString.EMPTYSTRING;
91         }
92       }
93       else
94       {
95         warn(xctxt, XPATHErrorResources.WG_DONT_DO_ANYTHING_WITH_NS,
96              new Object[]{ namespace,
97                            fullName });  //"Don't currently do anything with namespace "+namespace+" in property: "+fullName);
98 
99         try
100         {
101             //if secure procession is enabled only handle required properties do not not map any valid system property
102             if(!xctxt.isSecureProcessing())
103             {
104                 result = System.getProperty(propName);
105             }
106             else
107             {
108                 warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
109                         new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
110             }
111             if (null == result)
112             {
113                 return XString.EMPTYSTRING;
114             }
115         }
116         catch (SecurityException se)
117         {
118           warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
119                new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
120 
121           return XString.EMPTYSTRING;
122         }
123       }
124     }
125     else
126     {
127       try
128       {
129           //if secure procession is enabled only handle required properties do not not map any valid system property
130           if(!xctxt.isSecureProcessing())
131           {
132               result = System.getProperty(fullName);
133           }
134           else
135           {
136               warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
137                       new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
138           }
139           if (null == result)
140           {
141               return XString.EMPTYSTRING;
142           }
143       }
144       catch (SecurityException se)
145       {
146         warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION,
147              new Object[]{ fullName });  //"SecurityException when trying to access XSL system property: "+fullName);
148 
149         return XString.EMPTYSTRING;
150       }
151     }
152 
153     if (propName.equals("version") && result.length() > 0)
154     {
155       try
156       {
157         // Needs to return the version number of the spec we conform to.
158         return new XString("1.0");
159       }
160       catch (Exception ex)
161       {
162         return new XString(result);
163       }
164     }
165     else
166       return new XString(result);
167   }
168 
169   /**
170    * Retrieve a propery bundle from a specified file
171    *
172    * @param file The string name of the property file.  The name
173    * should already be fully qualified as path/filename
174    * @param target The target property bag the file will be placed into.
175    */
loadPropertyFile(String file, Properties target)176   public void loadPropertyFile(String file, Properties target)
177   {
178     try
179     {
180       // Use SecuritySupport class to provide priveleged access to property file
181       SecuritySupport ss = SecuritySupport.getInstance();
182 
183       InputStream is = ss.getResourceAsStream(ObjectFactory.findClassLoader(),
184                                               file);
185 
186       // get a buffered version
187       BufferedInputStream bis = new BufferedInputStream(is);
188 
189       target.load(bis);  // and load up the property bag from this
190       bis.close();  // close out after reading
191     }
192     catch (Exception ex)
193     {
194       // ex.printStackTrace();
195       throw new org.apache.xml.utils.WrappedRuntimeException(ex);
196     }
197   }
198 }
199