/* * Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.wso2.carbon.registry.jcr.query.qom; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.jcr.RegistryNode; import org.wso2.carbon.registry.jcr.RegistrySession; import org.wso2.carbon.registry.jcr.query.RegistryQueryResult; import org.wso2.carbon.registry.jcr.util.query.qom.QOMUtil; import javax.jcr.*; import javax.jcr.lock.LockException; import javax.jcr.nodetype.ConstraintViolationException; import javax.jcr.query.InvalidQueryException; import javax.jcr.query.QueryResult; import javax.jcr.query.qom.*; import javax.jcr.version.VersionException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.*; public class RegistryQueryObjectModel implements QueryObjectModel { private Source source = null; private Constraint constraint = null; private Ordering[] orderings = null; private Column[] columns = null; private RegistrySession session = null; private String statement = ""; private List sourceSet = new ArrayList(); public RegistryQueryObjectModel(Source source, Constraint constraint, Ordering[] orderings, Column[] columns, Session session) { this.source = source; this.constraint = constraint; if (orderings != null) { this.orderings = Arrays.copyOf(orderings, orderings.length); } if (columns != null) { this.columns = Arrays.copyOf(columns, columns.length); } this.session = (RegistrySession) session; } public Source getSource() { return source; } public Constraint getConstraint() { return constraint; } public Ordering[] getOrderings() { if (orderings != null) { return Arrays.copyOf(orderings, orderings.length); } else { return new Ordering[0]; } } public Column[] getColumns() { if (columns != null) { return Arrays.copyOf(columns, columns.length); } else { return new Column[0]; } } public List evaluateAnd(List set, Constraint andConstraint) throws RepositoryException { //mine List andResult = new ArrayList(); List result1; List result2; Constraint constraint1 = ((RegistryAnd) andConstraint).getConstraint1(); Constraint constraint2 = ((RegistryAnd) andConstraint).getConstraint2(); if (constraint1 instanceof And) { result1 = evaluateAnd(set, constraint1); } else { result1 = executeQuery(set, constraint1); } if (constraint2 instanceof And) { result2 = evaluateAnd(set, constraint2); } else { result2 = executeQuery(set, constraint2); } Iterator it1 = result1.iterator(); while (it1.hasNext()) { RegistryNode temp = (RegistryNode) it1.next(); Iterator it2 = result2.iterator(); while (it2.hasNext()) { if (temp.getPath().equals(((RegistryNode) it2.next()).getPath())) { andResult.add(temp); } } } return getfilteredFinalResult(set, andResult); } public List evaluateNot(List source_set, Constraint andConstraint) throws RepositoryException { //mine List result1; Constraint constraint1 = ((RegistryAnd) andConstraint).getConstraint1(); if (constraint1 instanceof Not) { result1 = evaluateNot(source_set, constraint1); } else { result1 = executeQuery(source_set, constraint1); } Iterator it1 = result1.iterator(); List tempSet = new ArrayList(); while (it1.hasNext()) { RegistryNode temp = (RegistryNode) it1.next(); Iterator it2 = source_set.iterator(); while (it2.hasNext()) { if (temp.getPath().equals(((RegistryNode) it2.next()).getPath())) { tempSet.add(temp); } } } source_set.removeAll(tempSet); return source_set; } public List evaluateComparison(List set, Constraint constraint) throws RepositoryException{ //mine Operand operand1 = ((RegistryComparison) constraint).getOperand1(); Operand operand2 = ((RegistryComparison) constraint).getOperand2(); Value scalarOperandValue = null; Value[] dynamicOperandValues = null; List resultSet = new ArrayList(); String operator = ((RegistryComparison) constraint).getOperator(); try { ValueFactory valueFactory = session.getValueFactory(); for (Object obj : set) { Node node = (Node) obj; if (operand1 instanceof PropertyValue) { String propName = ((PropertyValue) operand1).getPropertyName(); dynamicOperandValues = QOMUtil.getPropertyValueFromName(propName, node); if(dynamicOperandValues == null) { continue; } } else if (operand1 instanceof Literal) { dynamicOperandValues[0] = ((Literal) operand1).getLiteralValue(); } else if (operand1 instanceof BindVariableValue) { dynamicOperandValues[0] = valueFactory.createValue(((BindVariableValue) operand1).getBindVariableName()); } if (operand2 instanceof Literal) { scalarOperandValue = ((Literal) operand2).getLiteralValue(); } else if (operand2 instanceof BindVariableValue) { scalarOperandValue = valueFactory.createValue(((BindVariableValue) operand2).getBindVariableName()); } else if (operand2 instanceof PropertyValue) { String propName = ((PropertyValue) operand2).getPropertyName(); scalarOperandValue = QOMUtil.getPropertyValueFromName(propName, node)[0]; } for (Value value : dynamicOperandValues) { boolean comparison = QOMUtil.evalComparison(value, scalarOperandValue,operator); if (comparison) { resultSet.add(node); } } } } catch (RepositoryException e) { throw new RepositoryException("Error while executing query comparison " + e.getMessage()); } return resultSet; } /** * Tests whether the selector node is a child of a node reachable by absolute path path. * A node-tuple satisfies the constraint only if: * selectorNode.getParent().isSame(session.getNode(path)) * <p/> * Though we recieve a Set as the selector domain we query the result from the whole node tree workspace */ public List evaluateChildNode(List set, Constraint constraint) throws RepositoryException { //mine List result = new ArrayList(); String path = ((RegistryChildNode) constraint).getParentPath(); // String selector = ((RegistryChildNode) constraint).getSelectorName(); try { Iterator it = set.iterator(); RegistryNode node = null; while (it.hasNext()) { node = (RegistryNode) it.next(); if (node.getPath().contains(path)) { result.add(node); } } } catch (RepositoryException e) { e.printStackTrace(); } return getfilteredFinalResult(set, result); } public List evaluateDescendantNode(List set, Constraint constraint) throws RepositoryException { //mine //Done List result = new ArrayList(); String path = ((RegistryDescendantNode) constraint).getAncestorPath(); // String selector = ((RegistryDescendantNode) constraint).getSelectorName(); // The "set" has all selector nodes that "selectorname" has try { RegistryNode node = null; Iterator it = set.iterator(); while (it.hasNext()) { node = ((RegistryNode) it.next()); if (node.getPath().contains(path)) { result.add(node); } } } catch (RepositoryException e) { e.printStackTrace(); } return getfilteredFinalResult(set, result); } public List evaluateFullTextSearch(List set, Constraint constraint) { //mine // TODO return null; } public List evaluateOr(List set, Constraint constraint) throws RepositoryException { //mine List orResult; List result1; List result2; Constraint constraint1 = ((RegistryOr) constraint).getConstraint1(); Constraint constraint2 = ((RegistryOr) constraint).getConstraint2(); if (constraint1 instanceof Or) { result1 = evaluateOr(set, constraint1); } else { result1 = executeQuery(set, constraint1); } if (constraint2 instanceof Or) { result2 = evaluateOr(set, constraint2); } else { result2 = executeQuery(set, constraint2); } Iterator it1 = result1.iterator(); Iterator it2 = result2.iterator(); RegistryNode node1; RegistryNode node2; Iterator it; while (it1.hasNext()) { node1 = (RegistryNode) it1.next(); while (it2.hasNext()) { node2 = (RegistryNode) it2.next(); if (node1.getPath().equals(node2.getPath())) { result2.remove(node2); it2 = result2.iterator(); } } } result1.addAll(result2); orResult = result1; return getfilteredFinalResult(set, orResult); } public List evaluatePropertyExistence(List set, Constraint constraint) throws RepositoryException { //mine List result = new ArrayList(); // String selector = ((RegistryPropertyExistence) constraint).getSelectorName(); String propName = ((RegistryPropertyExistence) constraint).getPropertyName(); String query = "SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PROPERTY PP, " + "REG_RESOURCE_PROPERTY RP WHERE R.REG_PATH_ID=RP.REG_PATH_ID" + "AND R.REG_NAME IS NULL AND RP.REG_RESOURCE_NAME IS NULL " + "AND RP.REG_PROPERTY_ID=PP.REG_ID AND PP.REG_NAME=" + propName; statement = "org.wso2.registry.direct.query;;" + query; Iterator it = set.iterator(); RegistryNode node = null; while (it.hasNext()) { node = (RegistryNode) it.next(); if (node.hasProperty(propName)) { result.add(node); } } return getfilteredFinalResult(set, result); } public List evaluateSameNode(List set, Constraint constraint) throws RepositoryException { //mine RegistryNode node = null; List result = new ArrayList(); // String selector = ((RegistrySameNode) constraint).getSelectorName(); String path = ((RegistrySameNode) constraint).getPath(); try { node = (RegistryNode) session.getNode(path); result.add(node); // statement ="org.wso2.registry.direct.query;;SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PATH PT WHERE PT.REG_PATH_VALUE ='"+path+"' AND R.REG_PATH_ID=PT.REG_PATH_ID AND R.REG_RESOURCE_NAME IS NULL"; statement = "org.wso2.registry.direct.query;;SELECT R.REG_PATH_ID, R.REG_NAME FROM REG_RESOURCE R, REG_PATH PT WHERE PT.REG_PATH_VALUE ='" + path + "' AND R.REG_PATH_ID=PT.REG_PATH_ID AND R.REG_NAME IS NULL"; } catch (RepositoryException e) { } return getfilteredFinalResult(set, result); } private List getfilteredFinalResult(List source, List result) throws RepositoryException { List finalResult = new ArrayList(); Iterator it1 = source.iterator(); while (it1.hasNext()) { RegistryNode temp1 = (RegistryNode) it1.next(); Iterator it2 = result.iterator(); while (it2.hasNext()) { RegistryNode temp2 = (RegistryNode) it2.next(); if ((temp1.getPath()).equals(temp2.getPath())) { finalResult.add(temp1); } } } return finalResult; } private List executeLocalQuery(String sql) throws RepositoryException { Registry registry = session.getUserRegistry(); Resource q1 = null; List nodes = new ArrayList(); try { //these modifications are done so the queries are not stored in the registry // q1 = registry.newResource(); // // q1.setContent(sql); // // q1.setMediaType(RegistryConstants.SQL_QUERY_MEDIA_TYPE); // // q1.addProperty(RegistryConstants.RESULT_TYPE_PROPERTY_NAME, // // RegistryConstants.RESOURCES_RESULT_TYPE); // // registry.put(RegistryConstants.CONFIG_REGISTRY_BASE_PATH + RegistryConstants.QUERIES_COLLECTION_PATH + "/custom-queries", q1); Map parameters = new HashMap(); parameters.put("query", sql); // Resource result = registry.executeQuery(RegistryConstants.CONFIG_REGISTRY_BASE_PATH + RegistryConstants.QUERIES_COLLECTION_PATH + "/custom-queries", parameters); Resource result = registry.executeQuery(null, parameters); String[] paths = (String[]) result.getContent(); for (String path : paths) { nodes.add(session.getNode(path)); } } catch (RegistryException e) { e.printStackTrace(); } return nodes; } private List getSourceSet(String ntName) { Registry registry = session.getUserRegistry(); Resource q1 = null; String sql1 = "SELECT REG_PATH_ID, REG_NAME FROM REG_RESOURCE WHERE REG_DESCRIPTION ='" + ntName + "'"; List nodes = new ArrayList(); try { //these modifications are done so the queries are not stored in the registry /* q1 = registry.newResource(); q1.setContent(sql1); q1.setMediaType(RegistryConstants.SQL_QUERY_MEDIA_TYPE); q1.addProperty(RegistryConstants.RESULT_TYPE_PROPERTY_NAME, RegistryConstants.RESOURCES_RESULT_TYPE); registry.put(RegistryConstants.CONFIG_REGISTRY_BASE_PATH + RegistryConstants.QUERIES_COLLECTION_PATH + "/custom-queries", q1); */ Map parameters = new HashMap(); parameters.put("query", sql1); // Resource result = registry.executeQuery(RegistryConstants.CONFIG_REGISTRY_BASE_PATH + RegistryConstants.QUERIES_COLLECTION_PATH + "/custom-queries", parameters); Resource result = registry.executeQuery(null, parameters); String[] paths = (String[]) result.getContent(); for (String path : paths) { nodes.add(session.getNode(path)); } } catch (Exception e) { e.printStackTrace(); } return nodes; } /** * @return * @throws InvalidQueryException * @throws RepositoryException Constraints - And,Not,Comparison, ChildNode, , DescendantNode, FullTextSearch, Or, PropertyExistence, SameNode */ public QueryResult execute() throws InvalidQueryException, RepositoryException { QueryResult queryResult = null; if (source instanceof Selector) { // we do not support outer joins sourceSet = sourceSelector(source); } else if (source instanceof Join) { // we do not support outer joins yet sourceSet = sourceJoin(source); } List result = executeQuery(sourceSet, getConstraint()); queryResult = new RegistryQueryResult(result, session); return queryResult; } private List sourceSelector(Source source) { String ntName = ((RegistrySelector) source).getNodeTypeName(); return getSourceSet(ntName); } private List sourceJoin(Source source) { List joinSourceSet = new ArrayList(); // Source left = ((RegistryJoin) source).getLeft(); // Source right = ((RegistryJoin) source).getRight(); // Set leftSet; // Set rightSet; // // if (left instanceof Join) { // // leftSet = sourceJoin(left); // // } else if (left instanceof Selector) { // // leftSet = sourceSelector(left); // // } // // if (right instanceof Join) { // // rightSet = sourceJoin(right); // // } else if (left instanceof Selector) { // // rightSet = sourceSelector(right); // // } /** * Here consider the join type and then consider join condition to get the source set */ return joinSourceSet; } public List executeQuery(List sourceSet, Constraint constraint) throws RepositoryException { //mine List set = null; if (constraint instanceof And) { set = evaluateAnd(sourceSet, constraint); } else if (constraint instanceof Not) { set = evaluateNot(sourceSet, constraint); } else if (constraint instanceof Comparison) { set = evaluateComparison(sourceSet, constraint); } else if (constraint instanceof ChildNode) { set = evaluateChildNode(sourceSet, constraint); } else if (constraint instanceof DescendantNode) { set = evaluateDescendantNode(sourceSet, constraint); } else if (constraint instanceof FullTextSearch) { set = evaluateFullTextSearch(sourceSet, constraint); } else if (constraint instanceof Or) { set = evaluateOr(sourceSet, constraint); } else if (constraint instanceof PropertyExistence) { set = evaluatePropertyExistence(sourceSet, constraint); } else if (constraint instanceof SameNode) { set = evaluateSameNode(sourceSet, constraint); } return set; } public void setLimit(long l) { } public void setOffset(long l) { } public String getStatement() { return statement; } public String getLanguage() { return null; } public String getStoredQueryPath() throws ItemNotFoundException, RepositoryException { return null; } public Node storeAsNode(String s) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, UnsupportedRepositoryOperationException, RepositoryException { return null; } public void bindValue(String s, Value value) throws IllegalArgumentException, RepositoryException { } public String[] getBindVariableNames() throws RepositoryException { return new String[0]; } }