blob: 4aa282151b43afe1ffa8ca40f16580cc04835197 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.chemistry.opencmis.query.example;
import java.util.List;
import java.util.Map;
import org.antlr.runtime.RecognitionException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
import org.apache.chemistry.opencmis.server.support.TypeManager;
import org.apache.chemistry.opencmis.server.support.query.CmisSelector;
import org.apache.chemistry.opencmis.server.support.query.FunctionReference;
import org.apache.chemistry.opencmis.server.support.query.QueryObject;
import org.apache.chemistry.opencmis.server.support.query.QueryObject.SortSpec;
import org.apache.chemistry.opencmis.server.support.query.QueryUtilStrict;
/**
* Main entry point for the parser example. It takes a CMISQL query as input,
* parses it and generates again CMISQL as output when traversing the tree.
* Runs standalone without a server. Usually this code would be called from
* the CMIS Discovery Service in a CMIS server implementation.
*
*/
public class ExampleQueryProcessor {
public static void main(String[] args) {
String query = "SELECT cmis:name AS name, cmis:objectTypeId, SCORE() FROM cmis:document WHERE cmis:name LIKE 'My%'";
ExampleQueryProcessor processor = new ExampleQueryProcessor();
System.out.println("Original CMISQL query: " + query);
String response = processor.parseQuery(query);
System.out.println("Generated CMISQL query: " + response);
}
public String parseQuery(String queryString) {
StringBuffer generatedResponse = new StringBuffer();
// Instantiate a walker traversing the WHERE clause and generating the output string
ExampleQueryWalker walker = new ExampleQueryWalker();
// create type definitions, for this example we just create cmis:document
TypeManager typeManager = ExampleTypeManager.getInstance();
// create the parser helper class with type manager and walker
QueryUtilStrict queryUtil= new QueryUtilStrict(queryString, typeManager, walker);
try {
// parse the statement, then traverse it using out query walker
queryUtil.processStatement();
QueryObject qo = queryUtil.getQueryObject();
// The SELECT and FROM part is handled in the QueryObject, we just need to retrieve
// the results, and generte the SELECT string
String selFromPart = getSelectFromString(qo);
generatedResponse.append(selFromPart);
// get the generated string from our query walker and append it
String whereClause = walker.getResult();
generatedResponse.append(whereClause);
// The ORDER BY part is handled in the QueryObject, we just need to retrieve
// the results, and generte the ORDER BY string
generatedResponse.append(getOrderBy(qo));
// Finally we have the full statement and return is as result
return generatedResponse.toString();
} catch (RecognitionException e) {
String message = "Syntax error in query: " + queryUtil.getErrorMessage(e);
System.out.println(message);
throw new CmisInvalidArgumentException(message, e);
}
}
private String getSelectFromString(QueryObject qo) {
StringBuffer result = new StringBuffer();
result.append("SELECT");
List<CmisSelector> sels = qo.getSelectReferences();
boolean first = true;
for (CmisSelector sel : sels) {
if (first) {
first = false;
result.append(" ");
} else
result.append(", ");
appendSelector(result, sel);
}
result.append(" FROM");
Map<String, String> froms = qo.getTypes();
first = true;
for(String from : froms.keySet()) {
if (first) {
first = false;
result.append(" ");
} else
result.append(", ");
result.append(from);
}
result.append(" ");
return result.toString();
}
private void appendSelector(StringBuffer result, CmisSelector sel) {
result.append(sel.getName());
if (sel instanceof FunctionReference)
result.append("()");
if (null != sel.getAliasName()) {
result.append(" AS ");
result.append(sel.getAliasName());
}
}
private String getOrderBy(QueryObject qo) {
List<SortSpec> orderBys = qo.getOrderBys();
if (null == orderBys || orderBys.size() == 0)
return "";
StringBuffer result = new StringBuffer();
result.append(" ORDER BY");
boolean first = true;
for (SortSpec sp : orderBys) {
if (first) {
first = false;
result.append(" ");
} else
result.append(", ");
CmisSelector sel = sp.getSelector();
appendSelector(result, sel);
if (!sp.ascending)
result.append(" DESC");
}
return result.toString();
}
}