/** * OpenSpotLight - Open Source IT Governance Platform * * Copyright (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA * or third-party contributors as indicated by the @author tags or express * copyright attribution statements applied by the authors. All third-party * contributions are distributed under license by CARAVELATECH CONSULTORIA E * TECNOLOGIA EM INFORMATICA LTDA. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA * *********************************************************************** * OpenSpotLight - Plataforma de Governança de TI de Código Aberto * * Direitos Autorais Reservados (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA * EM INFORMATICA LTDA ou como contribuidores terceiros indicados pela etiqueta * @author ou por expressa atribuição de direito autoral declarada e atribuída pelo autor. * Todas as contribuições de terceiros estão distribuídas sob licença da * CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA. * * Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob os * termos da Licença Pública Geral Menor do GNU conforme publicada pela Free Software * Foundation. * * Este programa é distribuído na expectativa de que seja útil, porém, SEM NENHUMA * GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU ADEQUAÇÃO A UMA * FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor do GNU para mais detalhes. * * Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto com este * programa; se não, escreva para: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package org.openspotlight.graph.query; import static org.openspotlight.graph.query.ConditionalOperatorType.AND; import static org.openspotlight.graph.query.ConditionalOperatorType.OR; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.openspotlight.graph.exception.MetaNodeTypeNotFoundException; import org.openspotlight.graph.metadata.Metadata; import org.openspotlight.graph.query.info.SelectByLinkCountInfo; import org.openspotlight.graph.query.info.WhereByLinkCountInfo.SLWhereTypeInfo; import org.openspotlight.graph.query.info.WhereByLinkCountInfo.SLWhereTypeInfo.SLTypeStatementInfo; import org.openspotlight.graph.query.info.WhereByLinkCountInfo.SLWhereTypeInfo.SLTypeStatementInfo.SLConditionInfo; import org.openspotlight.storage.domain.StorageNode; /** * The Class SLSelectByLinkCountExecuteCommand. * * @author Vitor Hugo Chagas */ public class SelectByLinkCountExecuteCommand extends SelectAbstractCommand { /** * The Class LinkCountEvaluator. * * @author Vitor Hugo Chagas */ class LinkCountEvaluator { /** The mapper. */ private final LinkCountMapper mapper; /** The where type info. */ private final SLWhereTypeInfo whereTypeInfo; /** * Instantiates a new link count evaluator. * * @param whereTypeInfo the where type info * @param mapper the mapper */ private LinkCountEvaluator(final SLWhereTypeInfo whereTypeInfo, final LinkCountMapper mapper) { this.whereTypeInfo = whereTypeInfo; this.mapper = mapper; } /** * Evaluate. * * @param statementInfo the statement info * @param id the id * @return true, if successful */ private boolean evaluate(final SLTypeStatementInfo statementInfo, final String id) { boolean status = false; final List<SLConditionInfo> conditionInfoList = statementInfo .getConditionInfoList(); for (final SLConditionInfo conditionInfo: conditionInfoList) { final ConditionalOperatorType conditionalOperator = conditionInfo .getConditionalOperator(); if (conditionalOperator != null) { if (status && conditionalOperator.equals(OR)) { return true; } if (!status && conditionalOperator.equals(AND)) { return false; } } if (conditionInfo.getInnerStatementInfo() == null) { final int linkCount = mapper.getLinkCount(conditionInfo, id); if (conditionInfo.getRelationalOperator().equals( RelationalOperatorType.EQUAL)) { status = linkCount == conditionInfo.getValue(); } else if (conditionInfo.getRelationalOperator().equals( RelationalOperatorType.GREATER_THAN)) { status = linkCount > conditionInfo.getValue(); } else if (conditionInfo.getRelationalOperator().equals( RelationalOperatorType.GREATER_OR_EQUAL_THAN)) { status = linkCount >= conditionInfo.getValue(); } else if (conditionInfo.getRelationalOperator().equals( RelationalOperatorType.LESSER_THAN)) { status = linkCount < conditionInfo.getValue(); } else if (conditionInfo.getRelationalOperator().equals( RelationalOperatorType.LESSER_OR_EQUAL_THAN)) { status = linkCount <= conditionInfo.getValue(); } } else { status = evaluate(conditionInfo.getInnerStatementInfo(), id); } } return status; } /** * Evaluate. * * @param id the id * @return true, if successful */ private boolean evaluate(final String id) { return evaluate(whereTypeInfo.getTypeStatementInfo(), id); } } /** * The Class LinkCountMapper. * * @author Vitor Hugo Chagas */ class LinkCountMapper { /** The input node wrappers. */ private final List<StorageNode> inputNodeWrappers; /** The map. */ private final Map<SLConditionInfo, Map<String, Integer>> map = new HashMap<SLConditionInfo, Map<String, Integer>>(); /** The where type info. */ private final SLWhereTypeInfo whereTypeInfo; /** * Instantiates a new link count mapper. * * @param whereTypeInfo the where type info * @param inputNodeWrappers the input node wrappers */ private LinkCountMapper(final SLWhereTypeInfo whereTypeInfo, final List<StorageNode> inputNodeWrappers) { this.whereTypeInfo = whereTypeInfo; this.inputNodeWrappers = inputNodeWrappers; } /** * Creates the node occurences map. * * @param nodeWrappers the node wrappers * @return the map< string, integer> @ the SL persistent tree session exception */ private Map<String, Integer> createNodeOccurencesMap( final List<StorageNode> nodeWrappers) { final Map<String, Integer> map = new HashMap<String, Integer>(); for (final StorageNode nodeWrapper: nodeWrappers) { final String id = nodeWrapper.getKeyAsString(); map.put(id, 0); } return map; } /** * Gets the link count. * * @param conditionInfo the condition info * @param id the id * @return the link count */ private int getLinkCount(final SLConditionInfo conditionInfo, final String id) { return map.get(conditionInfo).get(id); } /** * Gets the node wrappers. * * @param pLinkNodes the link nodes * @param side the side * @return the node wrappers @ the SL persistent tree session exception */ private Collection<StorageNode> getNodeWrappers( final Collection<StorageNode> pLinkNodes, final SideType side) { // Collection<StorageNode> nodeWrappers = new // ArrayList<StorageNode>(); // Collection<PLinkNodeWrapper> pLinkNodeWrappers = // QuerySupport.wrapLinkNodes(pLinkNodes); // for (PLinkNodeWrapper linkNodeWrapper : pLinkNodeWrappers) { // String id = side.equals(SLSideType.A_SIDE) ? // linkNodeWrapper.getSourceID() : linkNodeWrapper.getTargetID(); // StorageNode pNode = commandDO.getTreeSession().getNodeByID(id); // StorageNode nodeWrapper = new StorageNode(pNode); // nodeWrappers.add(nodeWrapper); // } // return nodeWrappers; throw new UnsupportedOperationException(); } /** * Map. @ the SL persistent tree session exception */ private void map() { map(whereTypeInfo.getTypeStatementInfo()); } /** * Map. * * @param statementInfo the statement info @ the SL persistent tree session exception */ private void map(final SLTypeStatementInfo statementInfo) { // List<SLConditionInfo> conditionInfoList = // statementInfo.getConditionInfoList(); // for (SLConditionInfo conditionInfo : conditionInfoList) { // // if (conditionInfo.getInnerStatementInfo() == null) { // // if (inputNodeWrappers.isEmpty()) continue; // // Map<String, Integer> numberOcurrencesMap = // createNodeOccurencesMap(inputNodeWrappers); // map.put(conditionInfo, numberOcurrencesMap); // // XPathStatementBuilder statementBuilder = new // XPathStatementBuilder( // commandDO.getTreeSession().getXPathRootPath() // + "/links/*//*"); // Statement rootStatement = statementBuilder.getRootStatement(); // // SLSideType side = conditionInfo.getSide(); // String linkTypeHashPropName = // toInternalPropertyName(SLConsts.PROPERTY_NAME_LINK_TYPE_HASH); // String idPropName = // toInternalPropertyName(side.equals(SLSideType.A_SIDE) ? // SLConsts.PROPERTY_NAME_SOURCE_ID : // SLConsts.PROPERTY_NAME_TARGET_ID); // rootStatement.condition().leftOperand(linkTypeHashPropName).operator(EQUAL).rightOperand( // conditionInfo.getLinkTypeName().hashCode()); // // Statement statement = rootStatement.operator(AND).openBracket(); // for (int j = 0; j < inputNodeWrappers.size(); j++) { // Condition condition = j == 0 ? statement.condition() : // statement.operator(OR).condition(); // StorageNode pNodeWrapper = inputNodeWrappers.get(j); // condition.leftOperand(idPropName).operator(EQUAL).rightOperand(pNodeWrapper.getID()); // } // statement.closeBracket(); // // SLPersistentTreeSession treeSession = commandDO.getTreeSession(); // String xpath = statementBuilder.getXPath(); // SLPersistentQuery query = treeSession.createQuery(xpath, // SLPersistentQuery.TYPE_XPATH); // SLPersistentQueryResult result = query.execute(); // Collection<StorageNode> wrappers = // getNodeWrappers(result.getNodes(), conditionInfo.getSide()); // updateNumberOcurrences(numberOcurrencesMap, wrappers, // conditionInfo.getSide()); // } else { // map(conditionInfo.getInnerStatementInfo()); // } // } throw new UnsupportedOperationException(); } /** * Update number ocurrences. * * @param map the map * @param nodeWrappers the node wrappers * @param side the side @ the SL persistent tree session exception */ private void updateNumberOcurrences(final Map<String, Integer> map, final Collection<StorageNode> nodeWrappers, final SideType side) { for (final StorageNode nodeWrapper: nodeWrappers) { final String id = nodeWrapper.getKeyAsString(); final Integer occurences = map.get(id); map.put(id, occurences + 1); } } } /** The command do. */ private final SelectCommandDO commandDO; /** The metadata. */ private final Metadata metadata; /** The node wrapper list map. */ private Map<String, List<StorageNode>> nodeWrapperListMap; /** The select info. */ private final SelectByLinkCountInfo selectInfo; /** * Instantiates a new sL select by link count execute command. * * @param selectByLinkCountInfo the select by link count info * @param commandDO the command do */ public SelectByLinkCountExecuteCommand( final SelectByLinkCountInfo selectByLinkCountInfo, final SelectCommandDO commandDO) { selectInfo = selectByLinkCountInfo; this.commandDO = commandDO; metadata = commandDO.getMetadata(); } /** * Gets the p node wrappers of type. * * @param name the name * @return the p node wrappers of type @ the SL persistent tree session exception */ private List<StorageNode> getStorageNodesOfType(final String name) { // List<StorageNode> pNodeWrappers = new ArrayList<StorageNode>(); // XPathStatementBuilder statementBuilder = new // XPathStatementBuilder(commandDO.getTreeSession().getXPathRootPath() // + "/contexts//*"); // Statement rootStatement = statementBuilder.getRootStatement(); // String typePropName = // SLCommonSupport.toInternalPropertyName(SLConsts.PROPERTY_NAME_TYPE); // rootStatement.condition().leftOperand(typePropName).operator(EQUAL).rightOperand(name); // String xpath = statementBuilder.getXPath(); // SLPersistentQuery query = // commandDO.getTreeSession().createQuery(xpath, // SLPersistentQuery.TYPE_XPATH); // SLPersistentQueryResult result = query.execute(); // Collection<StorageNode> pNodes = result.getNodes(); // for (StorageNode pNode : pNodes) { // pNodeWrappers.add(new StorageNode(pNode)); // } // return pNodeWrappers; throw new UnsupportedOperationException(); } /** * Gets the where type info set. * * @return the where type info set */ private Set<SLWhereTypeInfo> getWhereTypeInfoSet() throws MetaNodeTypeNotFoundException { final Set<SLWhereTypeInfo> set = new HashSet<SLWhereTypeInfo>(); for (final SLWhereTypeInfo whereTypeInfo: selectInfo.getWhereStatementInfo() .getWhereTypeInfoList()) { final List<String> typeNames = QuerySupport.getHierarchyTypeNames( metadata, whereTypeInfo.getName(), whereTypeInfo.isSubTypes()); for (final String typeName: typeNames) { final SLWhereTypeInfo typeInfo = new SLWhereTypeInfo(typeName); typeInfo.setTypeStatementInfo(whereTypeInfo .getTypeStatementInfo()); set.add(typeInfo); } } return set; } /** * {@inheritDoc} */ @Override public void execute() { try { final Set<StorageNode> nodeWrappers = new HashSet<StorageNode>(); commandDO.setNodeWrappers(nodeWrappers); final Set<SLWhereTypeInfo> whereTypeInfoSet = getWhereTypeInfoSet(); if (commandDO.getPreviousNodeWrappers() != null) { nodeWrapperListMap = QuerySupport.mapNodesByType(commandDO .getPreviousNodeWrappers()); } else { nodeWrapperListMap = new HashMap<String, List<StorageNode>>(); for (final SLWhereTypeInfo whereTypeInfo: whereTypeInfoSet) { final List<StorageNode> wrappers = getStorageNodesOfType(whereTypeInfo .getName()); nodeWrapperListMap.put(whereTypeInfo.getName(), wrappers); } } for (final SLWhereTypeInfo whereTypeInfo: whereTypeInfoSet) { final List<StorageNode> inputNodeWrappers = nodeWrapperListMap .get(whereTypeInfo.getName()); final LinkCountMapper mapper = new LinkCountMapper(whereTypeInfo, inputNodeWrappers); mapper.map(); final LinkCountEvaluator evaluator = new LinkCountEvaluator( whereTypeInfo, mapper); for (final StorageNode nodeWrapper: inputNodeWrappers) { final String id = nodeWrapper.getKeyAsString(); final boolean status = evaluator.evaluate(id); if (status) { nodeWrappers.add(nodeWrapper); } } } } catch (final Exception e) { throw new QueryException("Error on attempt to execute " + this.getClass().getName() + " command."); } } }