/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.core.commons.services.tagging.manager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.olat.core.commons.persistence.DB;
import org.olat.core.commons.persistence.DBQuery;
import org.olat.core.commons.services.tagging.model.Tag;
import org.olat.core.commons.services.tagging.model.TagImpl;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.AssertException;
import org.olat.core.manager.BasicManager;
import org.olat.core.util.StringHelper;
/**
*
* Description:<br>
* TODO: srosse Class Description for TaggingManagerImpl
*
* <P>
* Initial Date: 19 jul. 2010 <br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*/
public class TaggingManagerImpl extends BasicManager implements TaggingManager {
private DB dbInstance;
private TagProposalManager proposalManager;
public TaggingManagerImpl() {
//
}
/**
* [used by Spring]
* @param dbInstance
*/
public void setDbInstance(DB dbInstance) {
this.dbInstance = dbInstance;
}
/**
* [used by Spring]
* @param proposalManager
*/
public void setProposalManager(TagProposalManager proposalManager) {
this.proposalManager = proposalManager;
}
@Override
public List<String> getTagsAsString(Identity identity, OLATResourceable ores, String subPath, String businessPath) {
if (ores.getResourceableId() == null || ores.getResourceableTypeName() == null){
// this ores seems not yet to be persisted, therefore has no key and as a result no tags!
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("select tag.tag from ").append(TagImpl.class.getName())
.append(" tag where tag.resId=:resId and tag.resName=:resName");
if(subPath != null) {
sb.append(" and tag.subPath=:subPath");
}
if (identity != null) {
sb.append(" and tag.author=:author");
}
if(businessPath != null) {
sb.append(" and tag.businessPath=:businessPath");
}
sb.append(" group by tag.tag");
DBQuery query = dbInstance.createQuery(sb.toString());
query.setLong("resId", ores.getResourceableId());
query.setString("resName", ores.getResourceableTypeName());
if(subPath != null) {
query.setString("subPath", subPath);
}
if (identity != null){
query.setEntity("author", identity);
}
if(businessPath != null) {
query.setString("businessPath", businessPath);
}
@SuppressWarnings("unchecked")
List<String> tags = query.list();
return tags;
}
@Override
public List<String> getUserTagsAsString(Identity identity){
if (identity == null) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select tag.tag from ").append(TagImpl.class.getName())
.append(" tag where tag.author=:author")
.append(" group by tag.tag")
.append(" order by count(tag.key) DESC");
DBQuery query = dbInstance.createQuery(sb.toString());
query.setEntity("author", identity);
@SuppressWarnings("unchecked")
List<String> tags = query.list();
return tags;
}
/**
* @see org.olat.core.commons.services.tagging.manager.TaggingManager#getUserTagsOfTypeAsString(org.olat.core.id.Identity, java.lang.String)
*/
@Override
public List<String> getUserTagsOfTypeAsString(Identity identity, String type) {
if (identity == null || !StringHelper.containsNonWhitespace(type)) return Collections.emptyList();
StringBuilder sb = new StringBuilder();
sb.append("select tag.tag from ").append(TagImpl.class.getName())
.append(" tag where tag.author=:author and tag.resName=:resName")
.append(" group by tag.tag")
.append(" order by count(tag.key) DESC");
DBQuery query = dbInstance.createQuery(sb.toString());
query.setEntity("author", identity);
query.setString("resName", type);
@SuppressWarnings("unchecked")
List<String> tags = query.list();
return tags;
}
@Override
public List<Map<String, Integer>> getUserTagsWithFrequency(Identity identity){
if (identity == null) return null;
StringBuilder sb = new StringBuilder();
sb.append("select new map ( tag.tag as tag, count(*) as nr ) from ").append(TagImpl.class.getName())
.append(" tag where tag.author=:author and tag.tag=tag.tag ")
.append("Group by tag.tag order by count(*) DESC, tag.tag ASC");
DBQuery query = dbInstance.createQuery(sb.toString());
query.setEntity("author", identity);
@SuppressWarnings("unchecked")
List<Map<String, Integer>> tags = query.list();
return tags;
}
@Override
public HashSet<OLATResourceable> getResourcesByTags(List<Tag> tagList){
if (tagList == null || tagList.size() == 0) return null;
StringBuilder sb = new StringBuilder();
sb.append("select tag from ").append(TagImpl.class.getName())
.append(" tag where tag in ( :tagList )");
DBQuery query = dbInstance.createQuery(sb.toString());
query.setParameterList("tagList", tagList);
@SuppressWarnings("unchecked")
List<Tag> resList = query.list();
HashSet<OLATResourceable> oresList = new HashSet<OLATResourceable>();
for (Iterator<Tag> iterator = resList.iterator(); iterator.hasNext();) {
Tag tag = iterator.next();
OLATResourceable ores = tag.getOLATResourceable();
oresList.add(ores);
}
return oresList;
}
@Override
public List<Tag> loadTagsForResource(OLATResourceable ores, String subPath, String businessPath) {
if (ores.getResourceableId() == null) return null;
StringBuilder sb = new StringBuilder();
sb.append("select tag from ").append(TagImpl.class.getName())
.append(" tag where tag.resId=:resId and tag.resName=:resName");
if(subPath != null) {
sb.append(" and tag.subPath=:subPath");
}
if(businessPath != null) {
sb.append(" and tag.businessPath=:businessPath");
}
DBQuery query = dbInstance.createQuery(sb.toString());
query.setLong("resId", ores.getResourceableId());
query.setString("resName", ores.getResourceableTypeName());
if(subPath != null) {
query.setString("subPath", subPath);
}
if(businessPath != null) {
query.setString("businessPath", businessPath);
}
@SuppressWarnings("unchecked")
List<Tag> tags = query.list();
return tags;
}
@Override
public Tag createAndPersistTag(Identity author, String tag, OLATResourceable ores, String subPath, String businessPath) {
if (author == null || !StringHelper.containsNonWhitespace(tag) || ores.getResourceableId() == null || ores.getResourceableTypeName() == null){
throw new AssertException("A tag cannot be created and persisted without an author, tag and a valid OlatResourcable");
}
if (tag.length() > 128){
// truncate
logWarn("tag was too long, truncated to 128 chars. Original: " + tag, null);
tag = tag.substring(0, 125) + "...";
}
TagImpl t = new TagImpl();
t.setAuthor(author);
t.setTag(tag.trim());
t.setResId(ores.getResourceableId());
t.setResName(ores.getResourceableTypeName());
t.setBusinessPath(businessPath);
t.setResSubPath(subPath);
dbInstance.saveObject(t);
return t;
}
@Override
public void updateTag(Tag updateTag) {
dbInstance.updateObject(updateTag);
}
@Override
public void deleteTag(Tag tagToDelete) {
dbInstance.deleteObject(tagToDelete);
}
@Override
public void deleteTags(OLATResourceable ores, String subPath, String businessPath) {
List<Object> values = new ArrayList<Object>();
List<Type> types = new ArrayList<Type>();
StringBuilder sb = new StringBuilder();
sb.append("from ").append(TagImpl.class.getName()).append(" where resId=? and resName=?");
values.add(ores.getResourceableId());
types.add(StandardBasicTypes.LONG);
values.add(ores.getResourceableTypeName());
types.add(StandardBasicTypes.STRING);
if(subPath != null) {
sb.append(" and resSubPath=?");
values.add(subPath);
types.add(StandardBasicTypes.STRING);
}
if(businessPath != null) {
sb.append(" and businessPath=?");
values.add(businessPath);
types.add(StandardBasicTypes.STRING);
}
int tagsDeleted = dbInstance.delete(sb.toString(), values.toArray(new Object[values.size()]),
types.toArray(new Type[types.size()]));
logAudit("Deleted " + tagsDeleted + " tags of resource: " + ores.getResourceableTypeName() + " :: " + ores.getResourceableId());
}
@Override
public List<String> proposeTagsForInputText(String referenceText, boolean onlyExisting) {
if(proposalManager != null) {
List<String> proposedTags = proposalManager.proposeTagsForInputText(referenceText, onlyExisting);
return proposedTags;
}
return Collections.emptyList();
}
@Override
public float calculateTagRelevance(Tag tag, List<Tag> tagList) {
return 0.0f;
}
}