/**
* Copyright 2012 Universitat Pompeu Fabra.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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 License for the specific language governing permissions and
* limitations under the License.
*
*
*/
package org.onexus.website.api.widgets.tags.tagstore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TagStore implements Serializable {
private static final Logger LOGGER = LoggerFactory.getLogger(TagStore.class);
private String namespace;
private String tableName;
private DataSource dataSource;
public TagStore(String namespace, DataSource dataSource) {
super();
this.namespace = namespace;
this.tableName = namespace.trim().replaceAll("[^a-zA-Z0-9]", "_");
this.dataSource = dataSource;
createNamespaceTable();
}
public String getNamespace() {
return namespace;
}
public Collection<String> getTagKeys() {
String sql = "SELECT DISTINCT `tagKey` AS `tagKey` FROM `" + tableName + "`";
List<String> tagKeys;
try {
tagKeys = executeCollection(sql, "tagKey");
} catch (SQLException e) {
String msg = "Error on getTagKeys() <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
return tagKeys;
}
public Collection<String> getTagValues(String tagKey) {
String sql = "SELECT `tagValue` FROM `" + tableName + "` WHERE `tagKey` = '" + tagKey + "'";
List<String> tagValues;
try {
tagValues = executeCollection(sql, "tagValue");
} catch (SQLException e) {
String msg = "Error on getTagValues('" + tagKey + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
return tagValues;
}
public void putTagValue(String tagKey, String tagValue) {
Collection<String> values = getTagValues(tagKey);
// Skip already tagged values
if (values.contains(tagValue)) {
return;
}
String sql = "INSERT INTO `" + tableName + "` (`tagKey`, `tagValue`) VALUES ('" + tagKey + "', '" + tagValue
+ "')";
try {
executeSQL(sql);
} catch (SQLException e) {
String msg = "Error on putTagValue('" + tagKey + "', '" + tagValue + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
}
public void removeTag(String tagKey) {
String sql = "DELETE FROM `" + tableName + "` WHERE `tagKey` = '" + tagKey + "'";
try {
executeSQL(sql);
} catch (SQLException e) {
String msg = "Error on removeTag('" + tagKey + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
}
public void putTagKey(String tagKey) {
String sql = "INSERT INTO `" + tableName + "` (`tagKey`, `tagValue`) VALUES ('" + tagKey + "', NULL)";
try {
executeSQL(sql);
} catch (SQLException e) {
String msg = "Error on putTagKey('" + tagKey + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
}
public List<String> getTagKeysByValue(String tagValue) {
String sql = "SELECT `tagKey` FROM `" + tableName + "` WHERE `tagValue` = '" + tagValue + "'";
List<String> tagKeys;
try {
tagKeys = executeCollection(sql, "tagKey");
} catch (SQLException e) {
String msg = "Error on getTagKeysByValues('" + tagValue + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
return tagKeys;
}
public void removeTagValue(String tagKey, String tagValue) {
String sql = "DELETE FROM `" + tableName + "` WHERE `tagKey` = '" + tagKey + "' AND `tagValue` = '"
+ tagValue + "'";
try {
executeSQL(sql);
} catch (SQLException e) {
String msg = "Error on removeTagValue('" + tagKey + "', '" + tagValue + "') <" + sql + ">";
LOGGER.error(msg);
throw new RuntimeException(msg, e);
}
}
private void createNamespaceTable() {
StringBuilder sql = new StringBuilder();
sql.append("CREATE TABLE IF NOT EXISTS `")
.append(tableName)
.append("` ( `tagKey` varchar(128) NOT NULL, `tagValue` varchar(128) DEFAULT NULL, UNIQUE (`tagKey`, `tagValue`))");
try {
executeSQL(sql.toString());
} catch (SQLException e) {
String msg = "Error creating table for namespace '" + namespace + "' with SQL <" + sql.toString() + ">";
LOGGER.error(msg, e);
throw new RuntimeException(msg, e);
}
}
private void executeSQL(String sql) throws SQLException {
Connection conn = dataSource.getConnection();
Statement st = conn.createStatement();
st.execute(sql);
st.close();
conn.close();
}
private List<String> executeCollection(String sql, String fieldName) throws SQLException {
Connection conn = dataSource.getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
List<String> result = new ArrayList<String>();
while (rs.next()) {
String value = rs.getString(fieldName);
if (value != null) {
result.add(value);
}
}
rs.close();
st.close();
conn.close();
return result;
}
}