{"id":469,"date":"2016-04-04T08:27:09","date_gmt":"2016-04-04T08:27:09","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=469"},"modified":"2016-04-04T08:29:18","modified_gmt":"2016-04-04T08:29:18","slug":"using-properties-files-to-load-extension-settings","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/using-properties-files-to-load-extension-settings\/","title":{"rendered":"Using properties files to load Extension settings"},"content":{"rendered":"<p>Often times server-side code requires a number of configuration parameters that can be easily tweaked without recompiling and re-deploying the Extension. In this article we will show\u00a0a useful and little known feature of SFS2X&#8217;s Extensions.<!--more--><\/p>\n<p>Did you know you can user properties files to store your Extension&#8217;s runtime configuration and have it loaded auto-magically for you? If you have carefully read <a href=\"http:\/\/docs2x.smartfoxserver.com\/AdvancedTopics\/server-side-extensions\" target=\"_blank\">the documentation<\/a>\u00a0you probably already\u00a0know this , otherwise keep reading&#8230;<\/p>\n<h2>\u00bb What is a &#8220;properties&#8221; file<\/h2>\n<p>In the Java SDK &#8220;properties&#8221; files are simple text files containing key value pairs such as these:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nlanguage=eng\r\ntimeout=100\r\nisActive=true\r\n<\/pre>\n<p>where the string on the left side of the equal sign represents the key and the one\u00a0on the right\u00a0represents\u00a0the corresponding value.<\/p>\n<p><strong>NOTE<\/strong>: there shouldn&#8217;t be spaces before and after the equal sign.<\/p>\n<h2>\u00bb\u00a0Extension&#8217;s default configuration<\/h2>\n<p>Every\u00a0SmartFoxServer 2X \u00a0Extension expects an optional\u00a0<strong>config.properties<\/strong> file located in the same deployment folder. If such file exists it will be auto loaded at init() time and all of its properties exposed via the\u00a0<strong>getConfigProperties()<\/strong> method, which returns a <a title=\"JDK Properties class\" href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/Properties.html\" target=\"_blank\">java.util.Properties<\/a>\u00a0object.<\/p>\n<p>Using the previous example properties file here&#8217;s how we can access its data at runtime:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Override\r\npublic void init()\r\n{\r\n\tProperties props = getConfigProperties();\r\n\r\n\tString language = props.getProperty(&quot;language&quot;);\r\n\tint timeout = Integer.parseInt(props.getProperty(&quot;timeout&quot;));\r\n\tboolean isActive = Boolean.parseBoolean(props.getProperty(&quot;isActive&quot;));\r\n}\r\n<\/pre>\n<p><em>Properties<\/em> objects treat every value as a String so we need to convert the <em>int<\/em> and <em>boolean<\/em> data from the file accordingly. We can also provide a default value for each key if we are not sure that an\u00a0item will be\u00a0present in config file. For instance:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nProperties props = getConfigProperties();\r\n\r\nString language = props.getProperty(&quot;language&quot;, &quot;eng&quot;);\r\n<\/pre>\n<p>In this case the &#8220;eng&#8221; value will be the default when the &#8220;language&#8221; key is not present in config.properties.<\/p>\n<h2>\u00bb\u00a0Using multiple or\u00a0custom Properties files.<\/h2>\n<p>You may also use multiple properties files to store other data from your Extension in the local file system. The Properties class exposes useful methods to save and load data to local disk both in text and xml format.<\/p>\n<p>Here&#8217;s an example of custom saving and loading a Properties instance (as text file):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nprivate Properties loadProps(String fileName)\r\n{\r\n\tProperties props = new Properties();\r\n\r\n\ttry\r\n    {\r\n\t\tprops.load(new FileInputStream(fileName));\r\n    }\r\n    catch (IOException e)\r\n    {\r\n    \t\/\/ Log error\r\n    }\r\n\r\n\treturn props;\r\n}\r\n\r\nprivate void saveProps(Properties props, String fileName)\r\n{\r\n\ttry\r\n\t{\r\n\t\tprops.store(new FileOutputStream(fileName), &quot;optional comments&quot;);\r\n\t}\r\n\tcatch (IOException e)\r\n\t{\r\n\t\t\/\/ Log error\r\n\t}\r\n}\r\n<\/pre>\n<p>The code should be self-explanatory. There is one\u00a0minor note for the <strong>store(&#8230;)<\/strong> method, which takes a 2nd parameter where you can specify comments that will be prepended to\u00a0the file.<\/p>\n<p><strong>NOTE:\u00a0<\/strong>if you&#8217;re using relative paths for loading\/storing files keep in mind that every Extensions sees the <strong>SFS2X\/<\/strong> folder as their root. If you are storing your files side by side with your Extension the relative path can be built like this:<\/p>\n<p style=\"padding-left: 30px;\"><strong>extensions\/&lt;your-ext-name&gt;\/&lt;filename&gt;.properties<\/strong><\/p>\n<h2>\u00bb\u00a0Conclusion<\/h2>\n<p>Storing your Extension&#8217;s\u00a0settings in the default <strong>config.properties\u00a0<\/strong>file can be very handy as you can reconfigure your code while\u00a0it runs, without the need of recompiling and re-deploying.<\/p>\n<p>A simple reload of the Extension will trigger the update of the settings or,\u00a0if you want to avoid any reloads at all, you can manage your own custom .properties files and reload them with specific Extension commands.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Often times server-side code requires a number of configuration parameters that can be easily tweaked without recompiling and re-deploying the Extension. In this article we will show\u00a0a useful and little known feature of SFS2X&#8217;s Extensions.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[62,31,63],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/469"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":11,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":480,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/469\/revisions\/480"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}