/* * Copyright (C) 2011 OSBI Ltd * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package org.saiku.adhoc.service; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.Enumeration; import java.util.Properties; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SaikuProperties extends Properties{ private static final long serialVersionUID = 4835692048422342660L; private static final Logger log = LoggerFactory.getLogger(SaikuProperties.class); private final PropertySource propertySource; private int populateCount; private static SaikuProperties instance = instance(); private static final String SAIKU_PROPERTIES = "saiku-adhoc.properties"; /** * Returns the singleton. * * @return Singleton instance */ private static synchronized SaikuProperties instance() { if (instance == null) { instance = new SaikuProperties(); instance.populate(); } return instance; } public SaikuProperties() { this.propertySource = new FilePropertySource(new File(SAIKU_PROPERTIES)); } public interface PropertySource { InputStream openStream(); boolean isStale(); String getDescription(); } static class FilePropertySource implements PropertySource { private final File file; private long lastModified; FilePropertySource(File file) { this.file = file; this.lastModified = 0; } public InputStream openStream() { try { this.lastModified = file.lastModified(); FileInputStream in = new FileInputStream(file); log.info("Opening properties file: '" + file + "'"); return in; } catch (FileNotFoundException e) { throw new RuntimeException ( "Error while opening properties file: '" + file + "'",e); } } public boolean isStale() { return file.exists() && file.lastModified() > this.lastModified; } public String getDescription() { return "file=" + file.getAbsolutePath() + " (exists=" + file.exists() + ")"; } } /** * Implementation of {@link PropertySource} which reads from a {@link URL}. */ static class UrlPropertySource implements PropertySource { private final URL url; private long lastModified; UrlPropertySource(URL url) { this.url = url; } private URLConnection getConnection() { try { return url.openConnection(); } catch (IOException e) { throw new RuntimeException ("Error while opening properties file '" + url + "'", e); } } public InputStream openStream() { try { final URLConnection connection = getConnection(); this.lastModified = connection.getLastModified(); return connection.getInputStream(); } catch (IOException e) { throw new RuntimeException( "Error while opening properties file '" + url + "'", e); } } public boolean isStale() { final long lastModified = getConnection().getLastModified(); return lastModified > this.lastModified; } public String getDescription() { return url.toExternalForm(); } } /** * Loads saiku.properties from: 1) the file "$PWD/" 2) CLASSPATH * 3) the system properties */ public void populate() { loadIfStale(propertySource); URL url = null; File file = new File(SAIKU_PROPERTIES); if (file.exists() && file.isFile()) { // Read properties file "saiku.properties" from PWD, if it exists. try { url = file.toURI().toURL(); } catch (MalformedURLException e) { log.warn( "Saiku: file '" + file.getAbsolutePath() + "' could not be loaded", e); } } else { // Then try load it from classloader url = SaikuProperties.class.getClassLoader().getResource( SAIKU_PROPERTIES); } if (url != null) { load(new UrlPropertySource(url)); } else { log.warn( "saiku-adhoc.properties can't be found under '" + new File(".").getAbsolutePath() + "' or classloader"); } // copy in all system properties which start with "saiku." int count = 0; for (Enumeration<Object> keys = System.getProperties().keys(); keys.hasMoreElements();) { String key = (String) keys.nextElement(); String value = System.getProperty(key); if (key.startsWith("saiku-adhoc.")) { if (log.isDebugEnabled()) { log.debug("System property : populate: key=" + key + ", value=" + value); } instance.setProperty(key, value); count++; } } if (populateCount++ == 0) { log.info( "Saiku: loaded " + count + " system properties"); } } private void loadIfStale(PropertySource source) { if (source.isStale()) { if (log.isDebugEnabled()) { log.debug("Saiku: loading " + source.getDescription()); } load(source); } } private void load(final PropertySource source) { try { instance.load(source.openStream()); if (populateCount == 0) { log.info( "Saiku: properties loaded from '" + source.getDescription() + "'"); instance.list(System.out); } } catch (IOException e) { log.error( "Saiku: error while loading properties " + "from '" + source.getDescription() + "' (" + e.getMessage() + ")"); } } public static final String baseURL = setupBaseURL(); private static String setupBaseURL(){ boolean test = PentahoSystem.getInitializedOK(); if (test){ return PentahoSystem.getApplicationContext().getFullyQualifiedServerURL(); } else{ return getPropString("saiku-adhoc.baseurl","http://localhost:8080/saiku-adhoc-webapp/rest/saiku-adhoc"); } } public static final String defaultPrptTemplate = getPropString("saiku-adhoc.default.template","jade_4_left_aligned_grid"); public static final String cdaUser = getPropString("saiku-adhoc.cda.user","joe"); public static final String cdaPassword = getPropString("saiku-adhoc.cda.password","password"); public static final String metadataFile = getPropString("saiku-adhoc.metadata.file","/metadata.xmi"); public static String temporaryPath = getPropString("saiku-adhoc.temp.path","tmp"); public static String temporarySolution = getPropString("saiku-adhoc.temp.solution","system"); private static Boolean getPropBoolean(String key, String defaultValue) { Boolean ret; if (instance.containsKey(key)) { ret = Boolean.parseBoolean(instance.getProperty(key)); } else { ret = Boolean.parseBoolean(defaultValue); } return ret; } private static String getPropString(String key, String defaultValue) { String ret; if (instance.containsKey(key)) { ret = instance.getProperty(key); } else { ret = defaultValue; } return ret; } }