001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.api.web;
021
022 import org.apache.commons.io.FileUtils;
023 import org.apache.commons.io.IOUtils;
024 import org.sonar.api.utils.SonarException;
025
026 import java.io.File;
027 import java.io.FileNotFoundException;
028 import java.io.IOException;
029 import java.io.InputStream;
030
031 /**
032 * It's useful in development environment to see browser rendering in real time while editing the template. To do that, just
033 * return an absolute path in the method getTemplatePath() :<br/>
034 * <pre>
035 * <code>
036 * protected String getTemplatePath() {
037 * return "/tmp/sample_dashboard_widget.erb";
038 * }
039 * </code>
040 * </pre>
041 * Build and deploy the plugin in /extensions/plugins. The file /tmp/sample_dashboard_widget.erb will be reloaded on each request.
042 * <p/>
043 * <br/>
044 * In production environment, you have to return the classloader path, for example "/org/sonar/myplugin/sample_dashboard_widget.erb".
045 *
046 * @since 1.11
047 */
048 public abstract class AbstractRubyTemplate {
049
050 private String cache = null;
051
052 public String getTemplate() {
053 String result = loadTemplateFromCache();
054 try {
055 if (result == null) {
056 result = loadTemplateFromClasspath();
057 }
058 if (result == null) {
059 result = loadTemplateFromAbsolutePath();
060 }
061 return result;
062
063 } catch (IOException e) {
064 throw new SonarException("Can not read the file " + getTemplatePath(), e);
065 }
066 }
067
068 private String loadTemplateFromAbsolutePath() throws IOException {
069 File file = new File(getTemplatePath());
070 if (file.exists()) {
071 // the result is not cached
072 return FileUtils.readFileToString(file);
073 }
074 throw new FileNotFoundException(getTemplatePath());
075 }
076
077 private String loadTemplateFromClasspath() throws IOException {
078 InputStream input = getClass().getResourceAsStream(getTemplatePath());
079 try {
080 if (input != null) {
081 cache = IOUtils.toString(input);
082 return cache;
083 }
084 } finally {
085 IOUtils.closeQuietly(input);
086 }
087 return null;
088 }
089
090 protected String loadTemplateFromCache() {
091 return cache;
092 }
093
094 /**
095 * the path of the template. In production environment, it's the classloader path (for example "/org/sonar/my_template.erb").
096 * In dev mode, it's useful to return an absolute path (for example C:/temp/my_template.erb). In such a case the result is not cached.
097 */
098 protected abstract String getTemplatePath();
099
100 }