Java tutorial
/** * openkm, Open Document Management System (http://www.openkm.com) * Copyright (c) 2006-2013 Paco Avila & Josep Llort * * No bytes were intentionally harmed during the development of this application. * * 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. * * This program 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 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.ikon.module.jcr; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Property; import javax.jcr.PropertyIterator; import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.Workspace; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; import javax.jcr.query.Row; import javax.jcr.query.RowIterator; import org.apache.commons.lang.NotImplementedException; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.commons.query.GQL; import org.apache.jackrabbit.core.query.QueryImpl; import org.apache.jackrabbit.core.query.lucene.QueryResultImpl; import org.apache.jackrabbit.util.ISO8601; import org.apache.jackrabbit.util.ISO9075; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ikon.bean.Document; import com.ikon.bean.Folder; import com.ikon.bean.Mail; import com.ikon.bean.PropertyGroup; import com.ikon.bean.QueryResult; import com.ikon.bean.Repository; import com.ikon.bean.ResultSet; import com.ikon.bean.form.FormElement; import com.ikon.bean.form.Input; import com.ikon.bean.form.Select; import com.ikon.cache.UserNodeKeywordsManager; import com.ikon.core.AccessDeniedException; import com.ikon.core.Config; import com.ikon.core.DatabaseException; import com.ikon.core.ParseException; import com.ikon.core.PathNotFoundException; import com.ikon.core.RepositoryException; import com.ikon.dao.DashboardDAO; import com.ikon.dao.QueryParamsDAO; import com.ikon.dao.bean.QueryParams; import com.ikon.dao.bean.cache.UserNodeKeywords; import com.ikon.module.SearchModule; import com.ikon.module.jcr.base.BaseDocumentModule; import com.ikon.module.jcr.base.BaseFolderModule; import com.ikon.module.jcr.base.BaseMailModule; import com.ikon.module.jcr.stuff.JCRUtils; import com.ikon.module.jcr.stuff.JcrSessionManager; import com.ikon.util.FormUtils; import com.ikon.util.UserActivity; public class JcrSearchModule implements SearchModule { private static Logger log = LoggerFactory.getLogger(JcrSearchModule.class); @Override public List<QueryResult> findByContent(String token, String words) throws IOException, ParseException, RepositoryException, DatabaseException { log.debug("findByContent({}, {})", token, words); QueryParams params = new QueryParams(); params.setContent(words); List<QueryResult> ret = find(token, params); log.debug("findByContent: {}", ret); return ret; } @Override public List<QueryResult> findByName(String token, String words) throws IOException, ParseException, RepositoryException, DatabaseException { log.debug("findByName({}, {})", token, words); QueryParams params = new QueryParams(); params.setName(words); List<QueryResult> ret = find(token, params); log.debug("findByName: {}", ret); return ret; } @Override public List<QueryResult> findByKeywords(String token, Set<String> words) throws IOException, ParseException, RepositoryException, DatabaseException { log.debug("findByKeywords({}, {})", token, words); QueryParams params = new QueryParams(); params.setKeywords(words); List<QueryResult> ret = find(token, params); log.debug("findByKeywords: {}", ret); return ret; } @Override public List<QueryResult> find(String token, QueryParams params) throws IOException, ParseException, RepositoryException, DatabaseException { log.debug("find({}, {})", token, params); List<QueryResult> ret = findPaginated(token, params, 0, Config.MAX_SEARCH_RESULTS).getResults(); log.debug("find: {}", ret); return ret; } @Override public ResultSet findPaginated(String token, QueryParams params, int offset, int limit) throws IOException, ParseException, RepositoryException, DatabaseException { log.debug("findPaginated({}, {}, {}, {})", new Object[] { token, params, offset, limit }); String type = null; String query = null; if (!"".equals(params.getStatementQuery()) && (Query.XPATH.equals(params.getStatementType()) || Query.SQL.equals(params.getStatementType()))) { query = params.getStatementQuery(); type = params.getStatementType(); } else { query = prepareStatement(params); type = Query.XPATH; } ResultSet rs = findByStatementPaginated(token, query, type, offset, limit); log.debug("findPaginated: {}", rs); return rs; } /** * Escape jcr:contains searchExp (view 6.6.5.2) Text.escapeIllegalXpathSearchChars(searchTerm).replaceAll("'", "''") * * @see http * ://svn.apache.org/repos/asf/jackrabbit/branches/2.2/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit * /util/Text.java * @see http://wiki.apache.org/jackrabbit/EncodingAndEscaping * @param str The String to be escaped. * @return The escaped String. */ private String escapeContains(String str) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); if (c == '!' || c == '(' || c == ':' || c == '^' || c == '"' || c == '[' || c == ']' || c == '{' || c == '}' || c == '?') { sb.append('\\'); } sb.append(c); } return sb.toString().replace("'", "''"); } /** * Escape XPath string * * @see org.apache.jackrabbit.util.Text.escapeIllegalXpathSearchChars(String s) * @param str The String to be escaped. * @return The escaped String. */ private String escapeXPath(String str) { String ret = str.replace("'", "''"); return ret; } /** * Prepare statement */ public String prepareStatement(QueryParams params) throws IOException, ParseException { log.debug("prepareStatement({})", params); StringBuilder sb = new StringBuilder(); // Clean params params.setName(params.getName() != null ? params.getName().trim() : ""); params.setContent(params.getContent() != null ? params.getContent().trim() : ""); params.setKeywords(params.getKeywords() != null ? params.getKeywords() : new HashSet<String>()); params.setCategories(params.getCategories() != null ? params.getCategories() : new HashSet<String>()); params.setMimeType(params.getMimeType() != null ? params.getMimeType().trim() : ""); params.setAuthor(params.getAuthor() != null ? params.getAuthor().trim() : ""); params.setPath(params.getPath() != null ? params.getPath().trim() : ""); params.setMailSubject(params.getMailSubject() != null ? params.getMailSubject().trim() : ""); params.setMailFrom(params.getMailFrom() != null ? params.getMailFrom().trim() : ""); params.setMailTo(params.getMailTo() != null ? params.getMailTo().trim() : ""); params.setProperties( params.getProperties() != null ? params.getProperties() : new HashMap<String, String>()); // Domains boolean document = (params.getDomain() & QueryParams.DOCUMENT) != 0; boolean folder = (params.getDomain() & QueryParams.FOLDER) != 0; boolean mail = (params.getDomain() & QueryParams.MAIL) != 0; log.debug("doc={}, fld={}, mail={}", new Object[] { document, folder, mail }); // Escape if (!params.getName().equals("")) { params.setName(escapeContains(params.getName())); } if (!params.getContent().equals("")) { params.setContent(escapeContains(params.getContent())); } if (!params.getContent().isEmpty() || !params.getName().isEmpty() || !params.getKeywords().isEmpty() || !params.getMimeType().isEmpty() || !params.getAuthor().isEmpty() || !params.getProperties().isEmpty() || !params.getMailSubject().isEmpty() || !params.getMailFrom().isEmpty() || !params.getMailTo().isEmpty() || (params.getLastModifiedFrom() != null && params.getLastModifiedTo() != null)) { // Construct the query sb.append("/jcr:root" + ISO9075.encodePath(params.getPath()) + "//*[@jcr:primaryType eq 'openkm:void'"); /** * DOCUMENT */ if (document) { sb.append(" or (@jcr:primaryType eq 'openkm:document'"); if (!params.getContent().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(openkm:content,'" + params.getContent() + "')"); } if (!params.getName().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(@openkm:name,'" + params.getName() + "')"); } if (!params.getKeywords().isEmpty()) { for (Iterator<String> it = params.getKeywords().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:keywords='" + escapeContains(it.next()) + "'"); } } if (!params.getCategories().isEmpty()) { for (Iterator<String> it = params.getCategories().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:categories='" + it.next() + "'"); } } if (!params.getMimeType().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:content/jcr:mimeType='" + params.getMimeType() + "'"); } if (!params.getAuthor().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:content/openkm:author='" + params.getAuthor() + "'"); } if (params.getLastModifiedFrom() != null && params.getLastModifiedTo() != null) { sb.append(" " + params.getOperator() + " "); sb.append("("); sb.append("@openkm:content/jcr:lastModified >= xs:dateTime('" + ISO8601.format(params.getLastModifiedFrom()) + "')"); sb.append(" and "); sb.append("@openkm:content/jcr:lastModified <= xs:dateTime('" + ISO8601.format(params.getLastModifiedTo()) + "')"); sb.append(")"); } sb.append(preparePropertyGroups(params)); sb.append(")"); } /** * FOLDER */ if (folder) { sb.append(" or (@jcr:primaryType eq 'openkm:folder'"); if (!params.getName().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(@openkm:name,'" + params.getName() + "')"); } if (!params.getKeywords().isEmpty()) { for (Iterator<String> it = params.getKeywords().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:keywords='" + escapeContains(it.next()) + "'"); } } if (!params.getCategories().isEmpty()) { for (Iterator<String> it = params.getCategories().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:categories='" + it.next() + "'"); } } if (params.getLastModifiedFrom() != null && params.getLastModifiedTo() != null) { sb.append(" " + params.getOperator() + " "); sb.append("("); sb.append( "@jcr:created >= xs:dateTime('" + ISO8601.format(params.getLastModifiedFrom()) + "')"); sb.append(" and "); sb.append("@jcr:created <= xs:dateTime('" + ISO8601.format(params.getLastModifiedTo()) + "')"); sb.append(")"); } sb.append(preparePropertyGroups(params)); sb.append(")"); } /** * MAIL */ if (mail) { sb.append(" or (@jcr:primaryType eq 'openkm:mail'"); if (!params.getContent().equals("")) { sb.append(" and jcr:contains(.,'" + params.getContent() + "')"); } if (!params.getMailSubject().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(@openkm:subject,'" + params.getMailSubject() + "')"); } if (!params.getMailFrom().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(@openkm:from,'" + params.getMailFrom() + "')"); } if (!params.getMailTo().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("jcr:contains(@openkm:to,'" + params.getMailTo() + "')"); } if (!params.getMimeType().equals("")) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:content/jcr:mimeType='" + params.getMimeType() + "'"); } if (!params.getKeywords().isEmpty()) { for (Iterator<String> it = params.getKeywords().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:keywords='" + escapeContains(it.next()) + "'"); } } if (!params.getCategories().isEmpty()) { for (Iterator<String> it = params.getCategories().iterator(); it.hasNext();) { sb.append(" " + params.getOperator() + " "); sb.append("@openkm:categories='" + it.next() + "'"); } } sb.append(preparePropertyGroups(params)); sb.append(")"); } sb.append("] order by @jcr:score descending"); } log.debug("prepareStatement: {}", sb.toString()); return sb.toString(); } /** * Create XPath related to property groups. */ private Object preparePropertyGroups(QueryParams params) throws IOException, ParseException { StringBuilder sb = new StringBuilder(); if (!params.getProperties().isEmpty()) { Map<PropertyGroup, List<FormElement>> formsElements = FormUtils .parsePropertyGroupsForms(Config.PROPERTY_GROUPS_XML); for (Iterator<Entry<String, String>> it = params.getProperties().entrySet().iterator(); it.hasNext();) { Entry<String, String> ent = it.next(); FormElement fe = FormUtils.getFormElement(formsElements, ent.getKey()); if (fe != null && ent.getValue() != null) { String valueTrimmed = ent.getValue().trim(); if (!valueTrimmed.equals("")) { sb.append(" " + params.getOperator() + " "); if (fe instanceof Select) { sb.append("@" + ent.getKey() + "='" + escapeXPath(valueTrimmed) + "'"); } else if (fe instanceof Input && ((Input) fe).getType().equals(Input.TYPE_DATE)) { String[] date = valueTrimmed.split(","); if (date.length == 2) { sb.append("@" + ent.getKey() + " >= '" + date[0] + "'"); sb.append(" and "); sb.append("@" + ent.getKey() + " <= '" + date[1] + "'"); } } else { sb.append("jcr:contains(@" + ent.getKey() + ",'" + escapeContains(valueTrimmed) + "')"); } } } } } return sb.toString(); } public List<QueryResult> findByStatement(String token, String statement, String type) throws RepositoryException, DatabaseException { log.debug("findByStatement({}, {})", token, statement); List<QueryResult> ret = findByStatementPaginated(token, statement, type, 0, Config.MAX_SEARCH_RESULTS) .getResults(); log.debug("findByStatement: {}", ret); return ret; } public ResultSet findByStatementPaginated(String token, String statement, String type, int offset, int limit) throws RepositoryException, DatabaseException { log.debug("findByStatement({}, {}, {}, {}, {})", new Object[] { token, statement, type, offset, limit }); ResultSet rs = new ResultSet(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } if (statement != null && !statement.equals("")) { Workspace workspace = session.getWorkspace(); QueryManager queryManager = workspace.getQueryManager(); Query query = queryManager.createQuery(statement, type); rs = executeQuery(session, query, offset, limit); } // Activity log UserActivity.log(session.getUserID(), "FIND_BY_STATEMENT", null, null, type + ", " + statement); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("findByStatement: {}", rs); return rs; } /** * Execute query */ private ResultSet executeQuery(Session session, Query query, int offset, int limit) throws RepositoryException { log.debug("executeQuery({}, {}, {}, {})", new Object[] { session, query, offset, limit }); ResultSet rs = new ResultSet(); try { ArrayList<QueryResult> al = new ArrayList<QueryResult>(); // http://n4.nabble.com/Query-performance-for-large-query-results-td531360.html ((QueryImpl) query).setLimit(limit); ((QueryImpl) query).setOffset(offset); QueryResultImpl result = (QueryResultImpl) query.execute(); RowIterator rit = result.getRows(); rs.setTotal(result.getTotalSize()); while (rit.hasNext()) { Row row = rit.nextRow(); QueryResult qr = queryRowResultDigester(session, row); al.add(qr); } rs.setResults(al); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } log.debug("executeQuery: {}", rs); return rs; } /** * Execute simple query */ private ResultSet executeSimpleQuery(Session session, String statement, int offset, int limit) throws RepositoryException { log.debug("executeSimpleQuery({}, {}, {}, {})", new Object[] { session, statement, offset, limit }); ResultSet rs = new ResultSet(); if (statement != null && !statement.equals("")) { if (!statement.contains("path:")) { statement = "path:\"/" + Repository.ROOT + "\" " + statement; } if (!statement.contains("limit:") && limit < Config.MAX_SEARCH_RESULTS) { StringBuilder sb = new StringBuilder(); sb.append("limit:").append(offset).append("..").append(offset + limit); statement = statement.concat(" ").concat(sb.toString()); } try { ArrayList<QueryResult> al = new ArrayList<QueryResult>(); log.info("Statement: {}", statement); RowIterator rit = GQL.execute(statement, session); rs.setTotal(rit.getSize()); while (rit.hasNext()) { Row row = rit.nextRow(); QueryResult qr = queryRowResultDigester(session, row); al.add(qr); } rs.setResults(al); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } } log.debug("executeSimpleQuery: {}", rs); return rs; } /** * Convert Row to QueryResult */ private QueryResult queryRowResultDigester(Session session, Row row) throws javax.jcr.PathNotFoundException, javax.jcr.RepositoryException { String path = row.getValue(JcrConstants.JCR_PATH).getString(); log.debug("queryRowResultDigester: {}", path); Node node = session.getRootNode().getNode(path.substring(1)); QueryResult qr = new QueryResult(); if (node.isNodeType(Document.CONTENT_TYPE)) { Document doc = BaseDocumentModule.getProperties(session, node.getParent()); qr.setDocument(doc); } else if (node.isNodeType(Document.TYPE)) { Document doc = BaseDocumentModule.getProperties(session, node); try { if (node.getParent().isNodeType(Mail.TYPE)) { qr.setAttachment(doc); } else { qr.setDocument(doc); } } catch (javax.jcr.AccessDeniedException e) { qr.setDocument(doc); } } else if (node.isNodeType(Folder.TYPE)) { Folder fld = BaseFolderModule.getProperties(session, node); qr.setFolder(fld); } else if (node.isNodeType(Mail.TYPE)) { Mail mail = BaseMailModule.getProperties(session, node); qr.setMail(mail); } qr.setScore(row.getValue(JcrConstants.JCR_SCORE).getLong()); Value excerpt = row.getValue("rep:excerpt(openkm:content)"); if (excerpt != null) { qr.setExcerpt(excerpt.getString()); } return qr; } @Override public long saveSearch(String token, QueryParams params) throws AccessDeniedException, RepositoryException, DatabaseException { log.debug("saveSearch({}, {})", token, params); Session session = null; long id = 0; if (Config.SYSTEM_READONLY) { throw new AccessDeniedException("System is in read-only mode"); } try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } params.setUser(session.getUserID()); id = QueryParamsDAO.create(params); // Activity log UserActivity.log(session.getUserID(), "SAVE_SEARCH", params.getName(), null, params.toString()); } catch (javax.jcr.RepositoryException e) { throw new RepositoryException(e.getMessage(), e); } catch (DatabaseException e) { throw e; } finally { if (token == null) JCRUtils.logout(session); } log.debug("saveSearch: {}", id); return id; } @Override public void updateSearch(String token, QueryParams params) throws AccessDeniedException, RepositoryException, DatabaseException { log.debug("updateSearch({}, {})", token, params); Session session = null; if (Config.SYSTEM_READONLY) { throw new AccessDeniedException("System is in read-only mode"); } try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } params.setUser(session.getUserID()); QueryParamsDAO.update(params); // Activity log UserActivity.log(session.getUserID(), "UPDATE_SEARCH", params.getName(), null, params.toString()); } catch (javax.jcr.RepositoryException e) { throw new RepositoryException(e.getMessage(), e); } catch (DatabaseException e) { throw e; } finally { if (token == null) JCRUtils.logout(session); } log.debug("updateSearch: void"); } @Override public QueryParams getSearch(String token, int qpId) throws PathNotFoundException, RepositoryException, DatabaseException { log.debug("getSearch({}, {})", token, qpId); QueryParams qp = new QueryParams(); Session session = null; try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } qp = QueryParamsDAO.findByPk(qpId); // If this is a dashboard user search, dates are used internally if (qp.isDashboard()) { qp.setLastModifiedFrom(null); qp.setLastModifiedTo(null); } // Activity log UserActivity.log(session.getUserID(), "GET_SAVED_SEARCH", Integer.toString(qpId), null, qp.toString()); } catch (javax.jcr.PathNotFoundException e) { log.warn(e.getMessage(), e); throw new PathNotFoundException(e.getMessage(), e); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getSearch: {}", qp); return qp; } @Override public List<QueryParams> getAllSearchs(String token) throws RepositoryException, DatabaseException { log.debug("getAllSearchs({})", token); List<QueryParams> ret = new ArrayList<QueryParams>(); Session session = null; try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } List<QueryParams> qParams = QueryParamsDAO.findByUser(session.getUserID()); for (Iterator<QueryParams> it = qParams.iterator(); it.hasNext();) { QueryParams qp = it.next(); if (!qp.isDashboard()) { ret.add(qp); } } // Activity log UserActivity.log(session.getUserID(), "GET_ALL_SEARCHS", null, null, null); } catch (javax.jcr.RepositoryException e) { throw new RepositoryException(e.getMessage(), e); } catch (DatabaseException e) { throw e; } finally { if (token == null) JCRUtils.logout(session); } log.debug("getAllSearchs: {}", ret); return ret; } @Override public void deleteSearch(String token, long qpId) throws AccessDeniedException, RepositoryException, DatabaseException { log.debug("deleteSearch({}, {})", token, qpId); Session session = null; if (Config.SYSTEM_READONLY) { throw new AccessDeniedException("System is in read-only mode"); } try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } QueryParams qp = QueryParamsDAO.findByPk(qpId); QueryParamsDAO.delete(qpId); // Purge visited nodes table if (qp.isDashboard()) { DashboardDAO.deleteVisitedNodes(session.getUserID(), qp.getName()); } // Activity log UserActivity.log(session.getUserID(), "DELETE_SAVED_SEARCH", Long.toString(qpId), null, null); } catch (DatabaseException e) { log.warn(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("deleteSearch: void"); } @Override public Map<String, Integer> getKeywordMap(String token, List<String> filter) throws RepositoryException, DatabaseException { log.debug("getKeywordMap({}, {})", token, filter); Map<String, Integer> cloud = null; if (Config.USER_KEYWORDS_CACHE) { cloud = getKeywordMapCached(token, filter); } else { cloud = getKeywordMapLive(token, filter); } log.debug("getKeywordMap: {}", cloud); return cloud; } /** * Get keyword map */ private Map<String, Integer> getKeywordMapLive(String token, List<String> filter) throws RepositoryException, DatabaseException { log.debug("getKeywordMapLive({}, {})", token, filter); String statement = "/jcr:root//*[@jcr:primaryType eq 'openkm:document' or @jcr:primaryType eq 'openkm:mail' or @jcr:primaryType eq 'openkm:folder']"; HashMap<String, Integer> cloud = new HashMap<String, Integer>(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } Workspace workspace = session.getWorkspace(); QueryManager queryManager = workspace.getQueryManager(); Query query = queryManager.createQuery(statement, Query.XPATH); javax.jcr.query.QueryResult qResult = query.execute(); for (NodeIterator nit = qResult.getNodes(); nit.hasNext();) { Node doc = nit.nextNode(); Value[] keywordsValue = doc.getProperty(com.ikon.bean.Property.KEYWORDS).getValues(); ArrayList<String> keywordCollection = new ArrayList<String>(); for (int i = 0; i < keywordsValue.length; i++) { keywordCollection.add(keywordsValue[i].getString()); } if (filter != null && keywordCollection.containsAll(filter)) { for (Iterator<String> it = keywordCollection.iterator(); it.hasNext();) { String keyword = it.next(); if (!filter.contains(keyword)) { Integer occurs = cloud.get(keyword) != null ? cloud.get(keyword) : 0; cloud.put(keyword, occurs + 1); } } } } } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getKeywordMapLive: {}", cloud); return cloud; } /** * Get keyword map */ private Map<String, Integer> getKeywordMapCached(String token, List<String> filter) throws RepositoryException, DatabaseException { log.debug("getKeywordMapCached({}, {})", token, filter); HashMap<String, Integer> keywordMap = new HashMap<String, Integer>(); Session session = null; try { // TODO This JCR Session could be removed if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } Collection<UserNodeKeywords> userDocKeywords = UserNodeKeywordsManager.get(session.getUserID()) .values(); for (Iterator<UserNodeKeywords> kwIt = userDocKeywords.iterator(); kwIt.hasNext();) { Set<String> docKeywords = kwIt.next().getKeywords(); if (filter != null && docKeywords.containsAll(filter)) { for (Iterator<String> itDocKeywords = docKeywords.iterator(); itDocKeywords.hasNext();) { String keyword = itDocKeywords.next(); if (!filter.contains(keyword)) { Integer occurs = keywordMap.get(keyword) != null ? keywordMap.get(keyword) : 0; keywordMap.put(keyword, occurs + 1); } } } } } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getKeywordMapCached: {}", keywordMap); return keywordMap; } @Override public List<Document> getCategorizedDocuments(String token, String categoryId) throws RepositoryException, DatabaseException { log.debug("getCategorizedDocuments({}, {})", token, categoryId); List<Document> documents = new ArrayList<Document>(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } Node category = session.getNodeByUUID(categoryId); for (PropertyIterator it = category.getReferences(); it.hasNext();) { Property refProp = it.nextProperty(); if (com.ikon.bean.Property.CATEGORIES.equals(refProp.getName())) { Node node = refProp.getParent(); if (node.isNodeType(Document.TYPE)) { Document doc = BaseDocumentModule.getProperties(session, node); documents.add(doc); } } } } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getCategorizedDocuments: {}", documents); return documents; } @Override public List<Folder> getCategorizedFolders(String token, String categoryId) throws RepositoryException, DatabaseException { log.debug("getCategorizedFolders({}, {})", token, categoryId); List<Folder> folders = new ArrayList<Folder>(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } Node category = session.getNodeByUUID(categoryId); for (PropertyIterator it = category.getReferences(); it.hasNext();) { Property refProp = it.nextProperty(); if (com.ikon.bean.Property.CATEGORIES.equals(refProp.getName())) { Node node = refProp.getParent(); if (node.isNodeType(Folder.TYPE)) { Folder fld = BaseFolderModule.getProperties(session, node); folders.add(fld); } } } } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getCategorizedFolders: {}", folders); return folders; } @Override public List<Mail> getCategorizedMails(String token, String categoryId) throws RepositoryException, DatabaseException { log.debug("getCategorizedMails({}, {})", token, categoryId); List<Mail> mails = new ArrayList<Mail>(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } Node category = session.getNodeByUUID(categoryId); for (PropertyIterator it = category.getReferences(); it.hasNext();) { Property refProp = it.nextProperty(); if (com.ikon.bean.Property.CATEGORIES.equals(refProp.getName())) { Node node = refProp.getParent(); if (node.isNodeType(Mail.TYPE)) { Mail mail = BaseMailModule.getProperties(session, node); mails.add(mail); } } } } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("getCategorizedMails: {}", mails); return mails; } @Override public List<Document> getDocumentsByKeyword(String token, String keyword) throws RepositoryException, DatabaseException { throw new NotImplementedException("getDocumentsByKeyword"); } @Override public List<Folder> getFoldersByKeyword(String token, String keyword) throws RepositoryException, DatabaseException { throw new NotImplementedException("getFoldersByKeyword"); } @Override public List<Mail> getMailsByKeyword(String token, String keyword) throws RepositoryException, DatabaseException { throw new NotImplementedException("getMailsByKeyword"); } @Override public List<Document> getDocumentsByPropertyValue(String token, String group, String property, String value) throws RepositoryException, DatabaseException { throw new NotImplementedException("getDocumentsByPropertyValue"); } @Override public List<Folder> getFoldersByPropertyValue(String token, String group, String property, String value) throws RepositoryException, DatabaseException { throw new NotImplementedException("getFoldersByPropertyValue"); } @Override public List<Mail> getMailsByPropertyValue(String token, String group, String property, String value) throws RepositoryException, DatabaseException { throw new NotImplementedException("getMailsByPropertyValue"); } @Override public List<QueryResult> findSimpleQuery(String token, String statement) throws RepositoryException, DatabaseException { log.debug("findSimpleQuery({}, {})", token, statement); List<QueryResult> ret = findSimpleQueryPaginated(token, statement, 0, Config.MAX_SEARCH_RESULTS) .getResults(); log.debug("findSimpleQuery: {}", ret); return ret; } @Override public ResultSet findSimpleQueryPaginated(String token, String statement, int offset, int limit) throws RepositoryException, DatabaseException { log.debug("findSimpleQueryPaginated({}, {}, {}, {})", new Object[] { token, statement, offset, limit }); ResultSet rs = new ResultSet(); Session session = null; try { if (token == null) { session = JCRUtils.getSession(); } else { session = JcrSessionManager.getInstance().get(token); } rs = executeSimpleQuery(session, statement, offset, limit); } catch (javax.jcr.RepositoryException e) { log.error(e.getMessage(), e); throw new RepositoryException(e.getMessage(), e); } finally { if (token == null) JCRUtils.logout(session); } log.debug("findSimpleQueryPaginated: {}", rs); return rs; } @Override public ResultSet findMoreLikeThis(String token, String uuid, int maxResults) throws RepositoryException, DatabaseException { throw new NotImplementedException("findMoreLikeThis"); } }