/** * Copyright (c) 2009-2014 Câmara dos Deputados. Todos os direitos reservados. * * e-Democracia é um software livre; você pode redistribuí-lo e/ou modificá-lo dentro * dos termos da Licença Pública Geral Menor GNU como publicada pela Fundação do * Software Livre (FSF); na versão 2.1 da Licença, ou (na sua opinião) qualquer versão. * * Este programa é distribuído na esperança de que possa ser útil, mas SEM NENHUMA GARANTIA; * sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou APLICAÇÃO EM PARTICULAR. * Veja a Licença Pública Geral Menor GNU para maiores detalhes. */ package br.gov.camara.edemocracia.portlets.wikilegis.service.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.handlers.BeanListHandler; import br.gov.camara.edemocracia.portlets.wikilegis.ArtigoDisplay; import br.gov.camara.edemocracia.portlets.wikilegis.ElementoDisplay; import br.gov.camara.edemocracia.portlets.wikilegis.EstruturaDisplay; import br.gov.camara.edemocracia.portlets.wikilegis.exporter.wrapper.ComentarioWrapper; import br.gov.camara.edemocracia.portlets.wikilegis.exporter.wrapper.ContribuicaoWrapper; import br.gov.camara.edemocracia.portlets.wikilegis.model.Artigo; import br.gov.camara.edemocracia.portlets.wikilegis.model.Contribuicao; import br.gov.camara.edemocracia.portlets.wikilegis.model.Estrutura; import br.gov.camara.edemocracia.portlets.wikilegis.service.ArtigoLocalServiceUtil; import br.gov.camara.edemocracia.portlets.wikilegis.service.ContribuicaoLocalServiceUtil; import br.gov.camara.edemocracia.portlets.wikilegis.service.EstruturaLocalServiceUtil; import br.gov.camara.edemocracia.portlets.wikilegis.service.WikiLegisService; import br.gov.camara.edemocracia.portlets.wikilegis.service.base.WikiLegisServiceBaseImpl; import com.liferay.portal.kernel.cache.MultiVMPoolUtil; import com.liferay.portal.kernel.cache.PortalCache; import com.liferay.portal.kernel.dao.jdbc.DataAccess; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.workflow.WorkflowConstants; import com.liferay.portal.model.Group; import com.liferay.portal.model.User; import com.liferay.portal.service.ClassNameLocalServiceUtil; import com.liferay.portal.service.GroupLocalServiceUtil; import com.liferay.portal.service.ServiceContext; import com.liferay.portlet.messageboards.model.MBMessage; import com.liferay.portlet.messageboards.model.MBMessageDisplay; import com.liferay.portlet.messageboards.model.MBThread; import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil; import com.liferay.portlet.messageboards.service.MBMessageServiceUtil; /** * The implementation of the wiki legis remote service. * * <p> * All custom service methods should be put in this class. Whenever methods are * added, rerun ServiceBuilder to copy their definitions into the * {@link br.gov.camara.edemocracia.portlets.wikilegis.service.WikiLegisService} * interface. * </p> * * <p> * Never reference this interface directly. Always use * {@link br.gov.camara.edemocracia.portlets.wikilegis.service.WikiLegisServiceUtil} * to access the wiki legis remote service. * </p> * * <p> * This is a remote service. Methods of this service are expected to have * security checks based on the propagated JAAS credentials because this service * can be accessed remotely. * </p> * * @author robson * @see br.gov.camara.edemocracia.portlets.wikilegis.service.base.WikiLegisServiceBaseImpl * @see br.gov.camara.edemocracia.portlets.wikilegis.service.WikiLegisServiceUtil */ public class WikiLegisServiceImpl extends WikiLegisServiceBaseImpl { private static final String CACHE_NAME = WikiLegisService.class.getName(); /** * Invalida o cache para o grupo especificado * * @param groupId */ private void invalidateCache(long groupId) { PortalCache _portalCache = MultiVMPoolUtil.getCache(CACHE_NAME); _portalCache.remove("wikilegiscacheall_" + groupId); _portalCache.remove("wikilegisstruct_" + groupId); } private int contaMensagens(long artigoId) throws SystemException { return MBMessageLocalServiceUtil.getDiscussionMessagesCount( Artigo.class.getName(), artigoId, WorkflowConstants.STATUS_ANY); } private int contaContribuicoes(long artigoId) throws SystemException { return ContribuicaoLocalServiceUtil.contaContribuicoes(artigoId); } /** * @param input * @return */ private ArtigoDisplay constroiArtigoDisplay(Artigo input) { int numeroMensagens; try { numeroMensagens = contaMensagens(input.getArtigoId()); } catch (SystemException e) { numeroMensagens = 0; } int numeroContribuicoes; try { numeroContribuicoes = contaContribuicoes(input.getArtigoId()); } catch (SystemException e) { numeroContribuicoes = 0; } return new ArtigoDisplay(input, numeroMensagens, numeroContribuicoes); } /** * Obtém informações para exibição de um artigo * * @param artigoId * @return * @throws PortalException * @throws SystemException */ public ArtigoDisplay getArtigoDisplay(long artigoId) throws PortalException, SystemException { Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); return constroiArtigoDisplay(artigo); } private Map<String, ElementoDisplay> obtemDadosCache(long groupId) { PortalCache _portalCache = MultiVMPoolUtil.getCache(CACHE_NAME); String key = "wikilegiscacheall_" + groupId; @SuppressWarnings("unchecked") Map<String, ElementoDisplay> cachedData = (Map<String, ElementoDisplay>) _portalCache .get(key); if (cachedData != null) { if (cachedData.isEmpty()) return cachedData; if (cachedData.values().iterator().next() instanceof ElementoDisplay) return cachedData; } return null; } private void atualizaCache(long groupId, Map<String, ElementoDisplay> map) { PortalCache _portalCache = MultiVMPoolUtil.getCache(CACHE_NAME); String key = "wikilegiscacheall_" + groupId; _portalCache.put(key, map); } /** * Lista todos os elementos da wikilegis especificada * * @param companyId * @param groupId * @return * @throws SystemException * @throws PortalException */ @Override public Collection<ElementoDisplay> listaElementos(long groupId) throws SystemException, PortalException { // TODO: Verificar permissões // Group group = GroupLocalServiceUtil.getGroup(groupId); // Verifica se está em cache Map<String, ElementoDisplay> cachedData = obtemDadosCache(groupId); if (cachedData != null) { if (cachedData.isEmpty()) return Collections.unmodifiableCollection(cachedData.values()); if (cachedData.values().iterator().next() instanceof ElementoDisplay) return Collections.unmodifiableCollection(cachedData.values()); } cachedData = new LinkedHashMap<String, ElementoDisplay>(); Map<Long, List<ArtigoDisplay>> artigos = ArtigoLocalServiceUtil .listaArtigoDisplay(groupId); for (ArtigoDisplay artigo : getArtigos(artigos, 0l)) { cachedData.put("a" + artigo.getId(), artigo); } List<Estrutura> nos = EstruturaLocalServiceUtil.listaTodos(groupId); for (Estrutura no : nos) { cachedData.put("e" + no.getEstruturaId(), new EstruturaDisplay(no)); for (ArtigoDisplay artigo : getArtigos(artigos, no.getEstruturaId())) { cachedData.put("a" + artigo.getId(), artigo); } } // Adiciona em cache atualizaCache(groupId, Collections.synchronizedMap(cachedData)); return Collections.unmodifiableCollection(cachedData.values()); } /** * Obtém os artigos a partir do mapa * * @param artigos * @param estruturaId * @return */ private List<ArtigoDisplay> getArtigos( Map<Long, List<ArtigoDisplay>> artigos, long estruturaId) { List<ArtigoDisplay> ret = artigos.get(estruturaId); if (ret == null) return Collections.emptyList(); else return ret; } /** * Monta a lista de estruturas para visualização no menu * * @param groupId * @return * @throws SystemException * @throws PortalException */ @Override public List<EstruturaDisplay> listaEstrutura(long groupId) throws SystemException, PortalException { // TODO Verificar acesso String key = "wikilegisstruct_" + groupId; PortalCache _portalCache = MultiVMPoolUtil.getCache(CACHE_NAME); @SuppressWarnings("unchecked") List<EstruturaDisplay> retorno = (List<EstruturaDisplay>) _portalCache .get(key); if (retorno != null) { if (retorno.isEmpty()) return retorno; if (retorno.get(0) instanceof EstruturaDisplay) return retorno; } List<Estrutura> raizes = EstruturaLocalServiceUtil.listaFilhos(groupId, 0L); retorno = new ArrayList<EstruturaDisplay>(); for (Estrutura raiz : raizes) { EstruturaDisplay raizDisplay = new EstruturaDisplay(raiz); retorno.add(raizDisplay); adicionaFilhos(raizDisplay, raiz); } _portalCache.put(key, retorno); return retorno; } /** * Adiciona os elementos filho, recursivamente * * @param paiDisplay * @param pai * @throws SystemException */ private void adicionaFilhos(EstruturaDisplay paiDisplay, Estrutura pai) throws SystemException { List<Estrutura> filhos = EstruturaLocalServiceUtil.listaFilhos( pai.getGroupId(), pai.getEstruturaId()); for (Estrutura filho : filhos) { EstruturaDisplay filhoDisplay = paiDisplay.adicionaFilho(filho); adicionaFilhos(filhoDisplay, filho); } } /** * Edita o artigo especificado, criando uma nova versão * * @param artigoId * @param estruturaId * @param textoArtigo * @param legislacaoVigente * @param anteriorArtigoId * @throws SystemException * @throws PortalException */ @Override public void editaArtigo(long artigoId, long estruturaId, long anteriorArtigoId, String textoArtigo, String legislacaoVigente) throws SystemException, PortalException { // TODO: Verificar permissões User user = getGuestOrUser(); Artigo artigo = ArtigoLocalServiceUtil.atualizaArtigo(user.getUserId(), artigoId, estruturaId, anteriorArtigoId, textoArtigo, legislacaoVigente); invalidateCache(artigo.getGroupId()); } /** * Exclui um artigo * * TODO Verificar permissões no modelo * * @param artigoId * @throws SystemException * @throws PortalException */ public void excluiArtigo(long artigoId) throws SystemException, PortalException { User user = getGuestOrUser(); Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); long groupId = artigo.getGroupId(); // TODO Verifica se tem permissões ArtigoLocalServiceUtil.excluiArtigo(artigo.getArtigoId()); invalidateCache(groupId); } /** * Cria um novo artigo * * @param groupId * @param noId * @param anteriorArtigoId * @param textoArtigo * @throws SystemException * @throws PortalException * * @return Artigo o artigo recém-criado */ @Override public Artigo criaArtigo(long groupId, long noId, long anteriorArtigoId, String textoArtigo, String legislacaoVigente) throws SystemException, PortalException { // TODO: Verificar permissões User user = getGuestOrUser(); Artigo artigo = ArtigoLocalServiceUtil.criaArtigo(groupId, noId, anteriorArtigoId, textoArtigo, legislacaoVigente); invalidateCache(artigo.getGroupId()); return artigo; } /** * Lista as contribuições para o artigo especificado * * @param artigoId * @return * @throws SystemException */ @Override public List<Contribuicao> listaContribuicoes(long artigoId) throws SystemException { // TODO: Verificar permissoes return ContribuicaoLocalServiceUtil.listaContribuicoes(artigoId); } /** * Adiciona uma contribuição no artigo especificado * * @param artigoId * @param textoArtigo * @param descricao * @throws SystemException * @throws PortalException */ @Override public void adicionaContribuicao(long artigoId, String textoArtigo, String descricao) throws SystemException, PortalException { // TODO: Verificar permissões User user = getGuestOrUser(); Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); long groupId = artigo.getGroupId(); ContribuicaoLocalServiceUtil.criaContribuicao(user.getUserId(), artigoId, textoArtigo, descricao); Map<String, ElementoDisplay> dados = obtemDadosCache(groupId); if (dados != null) { dados.put("a" + artigoId, constroiArtigoDisplay(artigo)); atualizaCache(groupId, dados); } } /** * Exclui uma contribuição * * @param contribuicaoId * @throws SystemException * @throws PortalException */ public void removeContribuicao(long contribuicaoId) throws SystemException, PortalException { // TODO: Verificar permissões User user = getGuestOrUser(); Contribuicao contribuicao = ContribuicaoLocalServiceUtil .getContribuicao(contribuicaoId); Artigo artigo = ArtigoLocalServiceUtil.getArtigo(contribuicao .getArtigoId()); long groupId = artigo.getGroupId(); long artigoId = artigo.getArtigoId(); ContribuicaoLocalServiceUtil.deleteContribuicao(contribuicao); Map<String, ElementoDisplay> dados = obtemDadosCache(groupId); if (dados != null) { dados.put("a" + artigoId, constroiArtigoDisplay(artigo)); atualizaCache(groupId, dados); } } /** * Lista os nós filhos da estrutura * * @param groupId * @param paiEstruturaId * @return * @throws SystemException * @throws PortalException */ @Override public List<Estrutura> listaEstruturaFilhos(long groupId, long paiEstruturaId) throws PortalException, SystemException { // TODO: Verificar permissões User user = getGuestOrUser(); Group group = GroupLocalServiceUtil.getGroup(groupId); return EstruturaLocalServiceUtil.listaFilhos(groupId, paiEstruturaId); } /** * Lista os artigos filhos do nó de estrutura especificado * * @param groupId * @param paiEstruturaId * @return * @throws PortalException * @throws SystemException */ @Override public List<Artigo> listaArtigos(long groupId, long paiEstruturaId) throws PortalException, SystemException { // TODO: Verificar permissões User user = getGuestOrUser(); Group group = GroupLocalServiceUtil.getGroup(groupId); return ArtigoLocalServiceUtil.listaArtigos(groupId, paiEstruturaId); } /** * Cria uma novo nó na estrutura * * @param groupId * @param paiId * @param antesDeId * @param nome * @throws SystemException * @throws PortalException * @return Estrutura recém-criada */ @Override public Estrutura criaEstrutura(long groupId, long paiId, long antesDeId, String nome) throws PortalException, SystemException { // TODO verificar permissões User user = getGuestOrUser(); Group group = GroupLocalServiceUtil.getGroup(groupId); Estrutura estrutura = EstruturaLocalServiceUtil.criaEstrutura(groupId, paiId, antesDeId, nome); invalidateCache(groupId); return estrutura; } /** * Obtém a estrutura com o identificador informado * * @param estruturaId * @return * @throws SystemException * @throws PortalException */ @Override public Estrutura getEstrutura(long estruturaId) throws PortalException, SystemException { Estrutura estrutura = EstruturaLocalServiceUtil .getEstrutura(estruturaId); // TODO Verificar permissões return estrutura; } /** * Obtém o artigo com o identificador informado * * @param artigoId * @return * @throws PortalException * @throws SystemException */ @Override public Artigo getArtigo(long artigoId) throws PortalException, SystemException { Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); // TODO Verificar permissões return artigo; } /** * Compara as versões de contribuições e com o artigo original * * @param artigoId * @param contribuicaoId1 * @param contribuicaoId2 * @return * @throws SystemException * @throws PortalException */ /* @Override public List<List<DiffResult>> comparaVersoes(long artigoId, long contribuicaoId1, long contribuicaoId2) throws PortalException, SystemException { String left, right; if (contribuicaoId1 == 0l) { left = ArtigoLocalServiceUtil.getArtigo(artigoId).getTexto(); } else { left = ContribuicaoLocalServiceUtil .getContribuicao(contribuicaoId1).getTexto(); } if (contribuicaoId2 == 0l) { right = ArtigoLocalServiceUtil.getArtigo(artigoId).getTexto(); } else { right = ContribuicaoLocalServiceUtil.getContribuicao( contribuicaoId2).getTexto(); } List<DiffResult>[] results = DiffUtil.diff(new StringReader(left), new StringReader(right)); return Arrays.asList(results); } */ /** * Atualiza um elemento da estrutura */ public Estrutura atualizaEstrutura(long estruturaId, long groupId, long estruturaPaiId, long depoisDeEstruturaId, String texto) throws PortalException, SystemException { Estrutura estrutura = EstruturaLocalServiceUtil.atualizaEstrutura( estruturaId, groupId, estruturaPaiId, depoisDeEstruturaId, texto); invalidateCache(groupId); return estrutura; } /** * Acrescenta um comentário * * @param artigoId * @param comentarioPaiId * @param texto * @throws SystemException * @throws PortalException */ public void postaComentario(long artigoId, long comentarioPaiId, String texto) throws PortalException, SystemException { User user = getGuestOrUser(); Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); long userId = user.getUserId(); String userName = user.getFullName(); long groupId = artigo.getGroupId(); String className = Artigo.class.getName(); long classPK = artigoId; long threadId; if (comentarioPaiId <= 0l) { MBMessageDisplay md = MBMessageLocalServiceUtil .getDiscussionMessageDisplay(userId, groupId, className, artigoId, WorkflowConstants.STATUS_ANY); MBThread thread = md.getThread(); threadId = thread.getThreadId(); comentarioPaiId = md.getTreeWalker().getRoot().getMessageId(); } else { MBMessage parent = MBMessageLocalServiceUtil .getMessage(comentarioPaiId); threadId = parent.getThreadId(); } String subject = Long.toString(classPK); ServiceContext serviceContext = new ServiceContext(); serviceContext.setAddCommunityPermissions(true); serviceContext.setAddGuestPermissions(true); MBMessageLocalServiceUtil.addDiscussionMessage(userId, userName, groupId, className, classPK, threadId, comentarioPaiId, subject, texto, serviceContext); Map<String, ElementoDisplay> dados = obtemDadosCache(groupId); if (dados != null) { dados.put("a" + artigoId, constroiArtigoDisplay(artigo)); atualizaCache(groupId, dados); } } /** * Exclui um comentário de uma mensagem * * @param artigoId * @param messageId * @throws PortalException * @throws SystemException */ public void excluiComentario(long artigoId, long messageId) throws PortalException, SystemException { Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); String className = Artigo.class.getName(); String permissionClassName = className; long permissionClassPK = artigoId; long groupId = artigo.getGroupId(); MBMessageServiceUtil.deleteDiscussionMessage(groupId, className, groupId, permissionClassName, permissionClassPK, 0l, messageId); // deleteDiscussionMessage(groupId, className, // artigoId, permissionClassName, permissionClassPK, messageId); Map<String, ElementoDisplay> dados = obtemDadosCache(groupId); if (dados != null) { dados.put("a" + artigoId, constroiArtigoDisplay(artigo)); atualizaCache(groupId, dados); } } /** * Atualiza um comentário * * @param body * @param artigoId * @param messageId * @param userId * @return * @throws PortalException * @throws SystemException */ public MBMessage atualizaComentario(String body, long artigoId, long messageId, long userId) throws PortalException, SystemException { Artigo artigo = ArtigoLocalServiceUtil.getArtigo(artigoId); long groupId = artigo.getGroupId(); String className = Artigo.class.getName(); long classPK = artigoId; String subject = Long.toString(classPK); ServiceContext serviceContext = new ServiceContext(); serviceContext.setAddGuestPermissions(true); MBMessage mbMessage = MBMessageLocalServiceUtil .updateDiscussionMessage(userId, messageId, className, classPK, subject, body, serviceContext); // updateDiscussionMessage(userId, messageId, subject, body, // WorkflowConstants.STATUS_ANY); Map<String, ElementoDisplay> dados = obtemDadosCache(groupId); if (dados != null) { dados.put("a" + artigoId, constroiArtigoDisplay(artigo)); atualizaCache(groupId, dados); } return mbMessage; } public Contribuicao atualizaContribuicao(long contribuicaoId, String textoArtigo, String descricao) throws PortalException, SystemException { Contribuicao contribuicao = ContribuicaoLocalServiceUtil .atualizaContribuicao(contribuicaoId, textoArtigo, descricao); Artigo artigo = ArtigoLocalServiceUtil.getArtigo(contribuicao .getArtigoId()); Map<String, ElementoDisplay> dados = obtemDadosCache(artigo .getGroupId()); if (dados != null) { dados.put("a" + contribuicao.getArtigoId(), constroiArtigoDisplay(artigo)); atualizaCache(artigo.getGroupId(), dados); } return contribuicao; } /** * Retorna uma lista de contribuições (wrapper) para exportação * */ public List<ContribuicaoWrapper> exportaContribuicoes(long groupId) throws SystemException{ //TODO Verificar Permissões String sql = " select SUBSTRING(a.texto , 1, 20) as artigo, c.userName as usuario ,c.texto as sugestao,c.descricao as justificativa ,c.data_ as data from CDWL_Contribuicao c " + " inner join CDWL_artigo a on a.artigoId = c.artigoId " + " where c.artigoId in ( select artigoId from CDWL_artigo where groupId = "+ Long.toString(groupId) +" )"; Connection conn = null; PreparedStatement pstmt = null ; try { conn = DataAccess.getConnection(); pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); BeanListHandler<ContribuicaoWrapper> contribuicaoHandler = new BeanListHandler<ContribuicaoWrapper>(ContribuicaoWrapper.class); List<ContribuicaoWrapper> retorno = contribuicaoHandler.handle(rs); return retorno; } catch (SQLException e) { throw new SystemException(e); } finally { DataAccess.cleanUp(pstmt); DataAccess.cleanUp(conn); } } /** * Retorna uma lista de comentários (wrapper) para exportação */ public List<ComentarioWrapper> exportaComentarios(long groupId) throws SystemException{ //TODO Verificar Permissões String sql = " select SUBSTRING(a.texto, 1, 20) as artigo, m.userName as usuario, m.body as comentario ,m.createDate as dataCriacao" + " from CDWL_Artigo a left join MbMessage m on m.classPK = a.artigoId " + " where m.classNameId = "+ ClassNameLocalServiceUtil.getClassNameId(Artigo.class) + " " + " and a.groupId = "+ Long.toString(groupId) +" " + " and m.groupId = "+ Long.toString(groupId) +" " + " and m.parentMessageId <> 0 " + " order by createDate "; Connection conn = null; PreparedStatement pstmt = null ; try { conn = DataAccess.getConnection(); pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); BeanListHandler<ComentarioWrapper> contribuicaoHandler = new BeanListHandler<ComentarioWrapper>(ComentarioWrapper.class); List<ComentarioWrapper> retorno = contribuicaoHandler.handle(rs); return retorno; } catch (SQLException e) { throw new SystemException(e); } finally { DataAccess.cleanUp(pstmt); DataAccess.cleanUp(conn); } } }