<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
- <dependency>
- <groupId>com.google.code.gson</groupId>
- <artifactId>gson</artifactId>
- <version>2.2.2</version>
- </dependency>
<!-- unit tests -->
<dependency>
*/
package org.sonar.batch.local;
-import com.google.common.io.Closeables;
-import com.google.gson.Gson;
-import org.apache.commons.dbcp.BasicDataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import com.google.common.io.Files;
+import com.google.common.io.InputSupplier;
import org.sonar.api.BatchComponent;
import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.bootstrap.LocalMode;
+import org.sonar.batch.bootstrap.TempDirectories;
+import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.net.URI;
-import java.sql.SQLException;
/**
* @since 3.4
*/
public class LocalDatabase implements BatchComponent {
- private static final Logger LOG = LoggerFactory.getLogger(LocalDatabase.class);
-
- public static final String API_SYNCHRO = "/api/synchro";
+ private static final String API_SYNCHRO = "/api/synchro";
private static final String DIALECT = "h2";
private static final String DRIVER = "org.h2.Driver";
private static final String URL = "jdbc:h2:";
private final Settings settings;
private final Server server;
private final HttpDownloader httpDownloader;
- private BasicDataSource dataSource;
+ private final TempDirectories tempDirectories;
- public LocalDatabase(LocalMode localMode, Settings settings, Server server, HttpDownloader httpDownloader) {
+ public LocalDatabase(LocalMode localMode, Settings settings, Server server, HttpDownloader httpDownloader, TempDirectories tempDirectories) {
this.localMode = localMode;
this.settings = settings;
this.server = server;
this.httpDownloader = httpDownloader;
+ this.tempDirectories = tempDirectories;
}
public void start() {
return;
}
- LOG.info("Download database");
- Path path = downloadDatabase();
+ File file = tempDirectories.getFile("local", "db.h2.db");
+ String h2DatabasePath = file.getAbsolutePath().replaceAll(".h2.db", "");
- LOG.info("Starting local database");
- replaceSettings(path);
- configureDataSource(path);
+ downloadDatabase(file);
+ replaceSettings(h2DatabasePath);
}
- private Path downloadDatabase() {
- InputStream stream = null;
+ private void downloadDatabase(File toFile) {
try {
- stream = httpDownloader.openStream(URI.create(server.getURL() + API_SYNCHRO));
- return new Gson().fromJson(new InputStreamReader(stream), Path.class);
- } finally {
- Closeables.closeQuietly(stream);
+ Files.copy(new InputSupplier<InputStream>() {
+ public InputStream getInput() {
+ return httpDownloader.openStream(URI.create(server.getURL() + API_SYNCHRO));
+ }
+ }, toFile);
+ } catch (IOException e) {
+ throw new SonarException("Unable to download database", e);
}
}
- static class Path {
- String path;
-
- String getName() {
- return path.replaceAll(".h2.db", "");
- }
- }
-
- public void stop() {
- try {
- dataSource.close();
- } catch (SQLException e) {
- // Ignore error
- }
- }
-
- private void replaceSettings(Path path) {
+ private void replaceSettings(String h2DatabasePath) {
settings
.setProperty(DatabaseProperties.PROP_DIALECT, DIALECT)
.setProperty(DatabaseProperties.PROP_DRIVER, DRIVER)
.setProperty(DatabaseProperties.PROP_USER, USER)
.setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD)
- .setProperty(DatabaseProperties.PROP_URL, URL + path.getName());
- }
-
- private void configureDataSource(Path path) {
- try {
- dataSource = new BasicDataSource();
- dataSource.setDriverClassName(DRIVER);
- dataSource.setUsername(USER);
- dataSource.setPassword(PASSWORD);
- dataSource.setUrl(URL + path.getName());
- } catch (Exception e) {
- throw new SonarException("Fail to start local database", e);
- }
+ .setProperty(DatabaseProperties.PROP_URL, URL + h2DatabasePath);
}
}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.core.persistence;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.SonarException;
+
+import javax.sql.DataSource;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public class DbTemplate implements ServerComponent {
+ private static final Logger LOG = LoggerFactory.getLogger(DbTemplate.class);
+
+ public DbTemplate copyTable(DataSource source, DataSource dest, String table, String query) {
+ LOG.info("Copy table " + table);
+
+ int colCount = getColumnCount(source, table);
+
+ truncate(dest, table);
+
+ Connection sourceConnection = null;
+ Statement sourceStatement = null;
+ ResultSet sourceResultSet = null;
+ Connection destConnection = null;
+ ResultSet destResultSet = null;
+ try {
+ sourceConnection = source.getConnection();
+ sourceStatement = sourceConnection.createStatement();
+ sourceResultSet = sourceStatement.executeQuery(query);
+
+ destConnection = dest.getConnection();
+ destConnection.setAutoCommit(false);
+
+ PreparedStatement destStatement = destConnection.prepareStatement("INSERT INTO " + table + " VALUES(" + StringUtils.repeat("?", ",", colCount) + ")");
+ while (sourceResultSet.next()) {
+ for (int col = 1; col <= colCount; col++) {
+ Object value = sourceResultSet.getObject(col);
+ destStatement.setObject(col, value);
+ }
+ destStatement.addBatch();
+ }
+
+ destStatement.executeBatch();
+ destConnection.commit();
+ destStatement.close();
+ } catch (SQLException e) {
+ throw new SonarException("Fail to copy table " + table, e);
+ } finally {
+ closeQuietly(destResultSet);
+ closeQuietly(destConnection);
+ closeQuietly(sourceResultSet);
+ closeQuietly(sourceStatement);
+ closeQuietly(sourceConnection);
+ }
+
+ return this;
+ }
+
+ public int getColumnCount(DataSource dataSource, String table) {
+ Connection connection = null;
+ ResultSet metaData = null;
+ try {
+ connection = dataSource.getConnection();
+ metaData = connection.getMetaData().getColumns(null, null, table, null);
+
+ int nbColumns = 0;
+ while (metaData.next()) {
+ nbColumns++;
+ }
+
+ return nbColumns;
+ } catch (SQLException e) {
+ throw new SonarException("Fail to get column count for table " + table, e);
+ } finally {
+ closeQuietly(metaData);
+ closeQuietly(connection);
+ }
+ }
+
+ public int getRowCount(BasicDataSource dataSource, String table) {
+ Connection connection = null;
+ Statement statement = null;
+ ResultSet resultSet = null;
+ try {
+ connection = dataSource.getConnection();
+ statement = connection.createStatement();
+ resultSet = statement.executeQuery("SELECT count(*) from " + table);
+
+ return resultSet.next() ? resultSet.getInt(1) : 0;
+ } catch (SQLException e) {
+ throw new SonarException("Fail to get row count for table " + table, e);
+ } finally {
+ closeQuietly(resultSet);
+ closeQuietly(statement);
+ closeQuietly(connection);
+ }
+ }
+
+ public DbTemplate truncate(DataSource dataSource, String table) {
+ Connection connection = null;
+ Statement statement = null;
+ try {
+ connection = dataSource.getConnection();
+ statement = connection.createStatement();
+ statement.executeUpdate("TRUNCATE TABLE " + table);
+ } catch (SQLException e) {
+ throw new SonarException("Fail to truncate table " + table, e);
+ } finally {
+ closeQuietly(statement);
+ closeQuietly(connection);
+ }
+
+ return this;
+ }
+
+ public BasicDataSource dataSource(String driver, String user, String password, String url) {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(driver);
+ dataSource.setUsername(user);
+ dataSource.setPassword(password);
+ dataSource.setUrl(url);
+ return dataSource;
+ }
+
+ public DbTemplate createSchema(DataSource dataSource, String dialect) {
+ Connection connection = null;
+ try {
+ connection = dataSource.getConnection();
+ DdlUtils.createSchema(connection, dialect);
+ } catch (SQLException e) {
+ throw new SonarException("Fail to createSchema local database schema", e);
+ } finally {
+ closeQuietly(connection);
+ }
+
+ return this;
+ }
+
+ private void closeQuietly(Connection connection) {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void closeQuietly(Statement statement) {
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void closeQuietly(ResultSet resultSet) {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ // ignore
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.core.persistence;
+
+import com.google.common.io.Files;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.utils.SonarException;
+
+import javax.sql.DataSource;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+public class LocalDatabaseFactory implements ServerComponent {
+ private static final String DIALECT = "h2";
+ private static final String DRIVER = "org.h2.Driver";
+ private static final String URL = "jdbc:h2:";
+ private static final String USER = "sonar";
+ private static final String PASSWORD = "sonar";
+
+ private final Database database;
+
+ public LocalDatabaseFactory(Database database) {
+ this.database = database;
+ }
+
+ public byte[] createDatabaseForLocalMode() {
+ String name = System.getenv("java.io") + System.nanoTime(); // TODO
+
+ try {
+ BasicDataSource destination = create(DIALECT, DRIVER, USER, PASSWORD, URL + name);
+ copy(database.getDataSource(), destination);
+ close(destination);
+
+ return dbFileContent(name);
+ } catch (SQLException e) {
+ throw new SonarException("Unable to create database for local mode", e);
+ }
+ }
+
+ private void copy(DataSource source, DataSource dest) {
+ new DbTemplate().copyTable(source, dest, "PROPERTIES", "SELECT * FROM PROPERTIES WHERE (USER_ID IS NULL) AND (RESOURCE_ID IS NULL) AND NOT (PROP_KEY LIKE '%.secured')")
+ .copyTable(source, dest, "RULES_PROFILES", "SELECT * FROM RULES_PROFILES")
+ .copyTable(source, dest, "RULES", "SELECT * FROM RULES")
+ .copyTable(source, dest, "RULES_PARAMETERS", "SELECT * FROM RULES_PARAMETERS")
+ .copyTable(source, dest, "ACTIVE_RULES", "SELECT * FROM ACTIVE_RULES")
+ .copyTable(source, dest, "ACTIVE_RULE_PARAMETERS", "SELECT * FROM ACTIVE_RULE_PARAMETERS")
+ .copyTable(source, dest, "METRICS", "SELECT * FROM METRICS");
+ }
+
+ private BasicDataSource create(String dialect, String driver, String user, String password, String url) {
+ BasicDataSource dataSource = new DbTemplate().dataSource(driver, user, password, url);
+ new DbTemplate().createSchema(dataSource, dialect);
+ return dataSource;
+ }
+
+ private void close(BasicDataSource dest) throws SQLException {
+ dest.close();
+ }
+
+ private byte[] dbFileContent(String name) {
+ try {
+ File dbFile = new File(name + ".h2.db");
+ byte[] content = Files.toByteArray(dbFile);
+ dbFile.delete();
+ return content;
+ } catch (IOException e) {
+ throw new SonarException("Unable to read h2 database file", e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Sonar, open source software quality management tool.
+ * Copyright (C) 2008-2012 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * Sonar is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * Sonar is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with Sonar; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+ */
+package org.sonar.core.persistence;
+
+import com.google.common.io.Files;
+import org.apache.commons.dbcp.BasicDataSource;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class LocalDatabaseFactoryTest extends AbstractDaoTestCase {
+ private LocalDatabaseFactory localDatabaseFactory;
+ private BasicDataSource dataSource;
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Before
+ public void setUp() {
+ localDatabaseFactory = new LocalDatabaseFactory(getDatabase());
+ }
+
+ @After
+ public void closeDatabase() throws SQLException {
+ if (dataSource != null) {
+ dataSource.close();
+ }
+ }
+
+ @Test
+ public void should_create_database() throws IOException {
+ setupData("should_create_database");
+
+ byte[] database = localDatabaseFactory.createDatabaseForLocalMode();
+ dataSource = createDatabase(database);
+
+ assertThat(rowCount("PROPERTIES")).isEqualTo(1);
+ assertThat(rowCount("PROJECTS")).isZero();
+ }
+
+ private BasicDataSource createDatabase(byte[] db) throws IOException {
+ File file = temporaryFolder.newFile("db.h2.db");
+ Files.write(db, file);
+ return new DbTemplate().dataSource("org.h2.Driver", "sonar", "sonar", "jdbc:h2:" + file.getAbsolutePath().replaceAll(".h2.db", ""));
+ }
+
+ private int rowCount(String table) {
+ return new DbTemplate().getRowCount(dataSource, table);
+ }
+}
--- /dev/null
+<dataset>
+ <properties id="1" prop_key="resourceProperty" text_value="value1" resource_id="1" user_id="[null]"/>
+ <properties id="2" prop_key="globalProperty" text_value="value2" resource_id="[null]" user_id="[null]"/>
+ <properties id="3" prop_key="userProperty" text_value="value3" resource_id="[null]" user_id="1"/>
+ <properties id="4" prop_key="property.secured" text_value="value4" resource_id="[null]" user_id="[null]"/>
+</dataset>
\ No newline at end of file
+++ /dev/null
-/*
- * Sonar, open source software quality management tool.
- * Copyright (C) 2008-2012 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * Sonar is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * Sonar is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sonar; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.server.database;
-
-import org.apache.commons.dbcp.BasicDataSource;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.utils.SonarException;
-import org.sonar.core.persistence.Database;
-import org.sonar.core.persistence.DdlUtils;
-
-import javax.sql.DataSource;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-public class LocalDatabaseFactory implements ServerComponent {
- private static final Logger LOG = LoggerFactory.getLogger(LocalDatabaseFactory.class);
-
- private static final String H2_DIALECT = "h2";
- private static final String H2_DRIVER = "org.h2.Driver";
- private static final String H2_URL = "jdbc:h2:";
- private static final String H2_USER = "sonar";
- private static final String H2_PASSWORD = "sonar";
-
- private Database database;
-
- public LocalDatabaseFactory(Database database) {
- this.database = database;
- }
-
- public String createDatabaseForLocalMode() throws SQLException {
- String name = "/tmp/" + System.nanoTime();
-
- DataSource source = database.getDataSource();
- BasicDataSource destination = dataSource(H2_DRIVER, H2_USER, H2_PASSWORD, H2_URL + name);
-
- create(destination, H2_DIALECT);
-
- copyTable(source, destination, "PROPERTIES", "SELECT * FROM PROPERTIES WHERE (USER_ID IS NULL) AND (RESOURCE_ID IS NULL)");
- copyTable(source, destination, "RULES_PROFILES", "SELECT * FROM RULES_PROFILES");
- copyTable(source, destination, "RULES", "SELECT * FROM RULES");
- copyTable(source, destination, "RULES_PARAMETERS", "SELECT * FROM RULES_PARAMETERS");
- copyTable(source, destination, "ACTIVE_RULES", "SELECT * FROM ACTIVE_RULES");
- copyTable(source, destination, "ACTIVE_RULE_PARAMETERS", "SELECT * FROM ACTIVE_RULE_PARAMETERS");
- copyTable(source, destination, "METRICS", "SELECT * FROM METRICS");
-
- destination.close();
-
- return new File(name + ".h2.db").getAbsolutePath();
- }
-
- private void copyTable(DataSource source, DataSource dest, String table, String query) throws SQLException {
- LOG.info("Copy table " + table);
-
- int colCount = getColumnCount(source, table);
-
- truncate(dest, table);
-
- Connection sourceConnection = null;
- Statement sourceStatement = null;
- ResultSet sourceResultSet = null;
- Connection destConnection = null;
- ResultSet destResultSet = null;
- try {
- sourceConnection = source.getConnection();
- sourceStatement = sourceConnection.createStatement();
- sourceResultSet = sourceStatement.executeQuery(query);
-
- destConnection = dest.getConnection();
- destConnection.setAutoCommit(false);
-
- PreparedStatement destStatement = destConnection.prepareStatement("INSERT INTO " + table + " VALUES(" + StringUtils.repeat("?", ",", colCount) + ")");
- while (sourceResultSet.next()) {
- for (int col = 1; col <= colCount; col++) {
- Object value = sourceResultSet.getObject(col);
- destStatement.setObject(col, value);
- }
- destStatement.addBatch();
- }
-
- destStatement.executeBatch();
- destConnection.commit();
- destStatement.close();
- } finally {
- closeQuietly(destResultSet);
- closeQuietly(destConnection);
- closeQuietly(sourceResultSet);
- closeQuietly(sourceStatement);
- closeQuietly(sourceConnection);
- }
- }
-
- private int getColumnCount(DataSource dataSource, String table) throws SQLException {
- Connection connection = null;
- ResultSet metaData = null;
- try {
- connection = dataSource.getConnection();
- metaData = connection.getMetaData().getColumns(null, null, table, null);
-
- int nbColumns = 0;
- while (metaData.next()) {
- nbColumns++;
- }
-
- return nbColumns;
- } finally {
- closeQuietly(metaData);
- closeQuietly(connection);
- }
- }
-
- private void truncate(DataSource dataSource, String table) throws SQLException {
- Connection connection = null;
- Statement statement = null;
- try {
- connection = dataSource.getConnection();
- statement = connection.createStatement();
- statement.executeUpdate("TRUNCATE TABLE " + table);
- } finally {
- closeQuietly(statement);
- closeQuietly(connection);
- }
- }
-
- private BasicDataSource dataSource(String driver, String user, String password, String url) {
- BasicDataSource dataSource = new BasicDataSource();
- dataSource.setDriverClassName(driver);
- dataSource.setUsername(user);
- dataSource.setPassword(password);
- dataSource.setUrl(url);
- return dataSource;
- }
-
- public void create(DataSource dataSource, String dialect) throws SQLException {
- Connection connection = null;
- try {
- connection = dataSource.getConnection();
- DdlUtils.createSchema(connection, dialect);
- } catch (SQLException e) {
- throw new SonarException("Fail to create local database schema", e);
- } finally {
- closeQuietly(connection);
- }
- }
-
- private void closeQuietly(Connection connection) {
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException e) {
- // ignore
- }
- }
- }
-
- private void closeQuietly(Statement statement) {
- if (statement != null) {
- try {
- statement.close();
- } catch (SQLException e) {
- // ignore
- }
- }
- }
-
- private void closeQuietly(ResultSet resultSet) {
- if (resultSet != null) {
- try {
- resultSet.close();
- } catch (SQLException e) {
- // ignore
- }
- }
- }
-}
import org.sonar.server.configuration.Backup;
import org.sonar.server.configuration.ProfilesManager;
import org.sonar.server.database.EmbeddedDatabaseFactory;
-import org.sonar.server.database.LocalDatabaseFactory;
+import org.sonar.core.persistence.LocalDatabaseFactory;
import org.sonar.server.notifications.NotificationService;
import org.sonar.server.notifications.reviews.ReviewsNotificationManager;
import org.sonar.server.plugins.ApplicationDeployer;
# curl http://localhost:9000/api/synchro -v
def index
- database_factory = java_facade.getCoreComponentByClassname('org.sonar.server.database.LocalDatabaseFactory')
+ database_factory = java_facade.getCoreComponentByClassname('org.sonar.core.persistence.LocalDatabaseFactory')
- path = database_factory.createDatabaseForLocalMode()
+ dbFileContent = database_factory.createDatabaseForLocalMode()
- hash = {:path => path}
-
- respond_to do |format|
- format.json { render :json => jsonp(hash) }
- end
+ send_data String.from_java_bytes(dbFileContent)
end
end