mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged CMIS063 to HEAD
17143: Add Alfresco Restful Binding Reference link to CMIS Front Page 17144: Fix up link - not hard code to localhost. 17150: Updates for CMIS going to Public Review. 17151: CMIS 1.0cd04 update 17186: CMIS Query updates - part of MOB-232 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@17261 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -60,12 +60,20 @@ public interface CMISDictionaryService
|
|||||||
public CMISTypeDefinition findTypeForClass(QName clazz, CMISScope... matchingScopes);
|
public CMISTypeDefinition findTypeForClass(QName clazz, CMISScope... matchingScopes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find type for table
|
* Find a type by its query name
|
||||||
*
|
*
|
||||||
* @param tableName
|
* @param queryName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public CMISTypeDefinition findTypeForTable(String tableName);
|
public CMISTypeDefinition findTypeByQueryName(String queryName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a property by its query name
|
||||||
|
*
|
||||||
|
* @param queryName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CMISPropertyDefinition findPropertyByQueryName(String queryName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Base Types
|
* Get Base Types
|
||||||
|
@@ -126,13 +126,14 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea
|
|||||||
Map<QName, CMISAbstractTypeDefinition> assocDefsByQName = new HashMap<QName, CMISAbstractTypeDefinition>();
|
Map<QName, CMISAbstractTypeDefinition> assocDefsByQName = new HashMap<QName, CMISAbstractTypeDefinition>();
|
||||||
Map<CMISTypeId, CMISAbstractTypeDefinition> objectDefsByTypeId = new HashMap<CMISTypeId, CMISAbstractTypeDefinition>();
|
Map<CMISTypeId, CMISAbstractTypeDefinition> objectDefsByTypeId = new HashMap<CMISTypeId, CMISAbstractTypeDefinition>();
|
||||||
Map<CMISTypeId, CMISTypeDefinition> typeDefsByTypeId = new HashMap<CMISTypeId, CMISTypeDefinition>();
|
Map<CMISTypeId, CMISTypeDefinition> typeDefsByTypeId = new HashMap<CMISTypeId, CMISTypeDefinition>();
|
||||||
Map<String, CMISTypeDefinition> typeDefsByTable = new HashMap<String, CMISTypeDefinition>();
|
Map<String, CMISTypeDefinition> typeDefsByQueryName = new HashMap<String, CMISTypeDefinition>();
|
||||||
List<CMISTypeDefinition> baseTypes = new ArrayList<CMISTypeDefinition>();
|
List<CMISTypeDefinition> baseTypes = new ArrayList<CMISTypeDefinition>();
|
||||||
|
|
||||||
// Property Definitions Index
|
// Property Definitions Index
|
||||||
Map<String, CMISPropertyDefinition> propDefsById = new HashMap<String, CMISPropertyDefinition>();
|
Map<String, CMISPropertyDefinition> propDefsById = new HashMap<String, CMISPropertyDefinition>();
|
||||||
Map<QName, CMISPropertyDefinition> propDefsByQName = new HashMap<QName, CMISPropertyDefinition>();
|
Map<QName, CMISPropertyDefinition> propDefsByQName = new HashMap<QName, CMISPropertyDefinition>();
|
||||||
Map<CMISPropertyId, CMISPropertyDefinition> propDefsByPropId = new HashMap<CMISPropertyId, CMISPropertyDefinition>();
|
Map<CMISPropertyId, CMISPropertyDefinition> propDefsByPropId = new HashMap<CMISPropertyId, CMISPropertyDefinition>();
|
||||||
|
Map<String, CMISPropertyDefinition> propDefsByQueryName = new HashMap<String, CMISPropertyDefinition>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register Type Definition
|
* Register Type Definition
|
||||||
@@ -163,7 +164,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeDefsByTypeId.put(typeDef.getTypeId(), typeDef);
|
typeDefsByTypeId.put(typeDef.getTypeId(), typeDef);
|
||||||
typeDefsByTable.put(typeDef.getQueryName().toLowerCase(), typeDef);
|
typeDefsByQueryName.put(typeDef.getQueryName().toLowerCase(), typeDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
@@ -191,6 +192,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea
|
|||||||
propDefsByPropId.put(propDef.getPropertyId(), propDef);
|
propDefsByPropId.put(propDef.getPropertyId(), propDef);
|
||||||
propDefsByQName.put(propDef.getPropertyId().getQName(), propDef);
|
propDefsByQName.put(propDef.getPropertyId().getQName(), propDef);
|
||||||
propDefsById.put(propDef.getPropertyId().getId().toLowerCase(), propDef);
|
propDefsById.put(propDef.getPropertyId().getId().toLowerCase(), propDef);
|
||||||
|
propDefsByQueryName.put(propDef.getQueryName().toLowerCase(), propDef);
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
@@ -304,12 +306,22 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea
|
|||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#findTypeForTable(java.lang.String)
|
* @see org.alfresco.cmis.dictionary.CMISDictionaryService#findTypeForTable(java.lang.String)
|
||||||
*/
|
*/
|
||||||
public CMISTypeDefinition findTypeForTable(String tableName)
|
public CMISTypeDefinition findTypeByQueryName(String queryName)
|
||||||
{
|
{
|
||||||
CMISTypeDefinition typeDef = getRegistry().typeDefsByTable.get(tableName.toLowerCase());
|
CMISTypeDefinition typeDef = getRegistry().typeDefsByQueryName.get(queryName.toLowerCase());
|
||||||
return typeDef;
|
return typeDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.cmis.CMISDictionaryService#findPropertyByQueryName(java.lang.String)
|
||||||
|
*/
|
||||||
|
public CMISPropertyDefinition findPropertyByQueryName(String queryName)
|
||||||
|
{
|
||||||
|
CMISPropertyDefinition propertyDef = getRegistry().propDefsByQueryName.get(queryName.toLowerCase());
|
||||||
|
return propertyDef;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.cmis.CMISDictionaryService#getBaseTypes()
|
* @see org.alfresco.cmis.CMISDictionaryService#getBaseTypes()
|
||||||
|
@@ -126,6 +126,7 @@ public class CMISQueryParser
|
|||||||
CMISLexer lexer = new CMISLexer(cs);
|
CMISLexer lexer = new CMISLexer(cs);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
parser = new CMISParser(tokens);
|
parser = new CMISParser(tokens);
|
||||||
|
parser.setStrict(options.getQueryMode() == CMISQueryMode.CMS_STRICT);
|
||||||
CommonTree queryNode = (CommonTree) parser.query().getTree();
|
CommonTree queryNode = (CommonTree) parser.query().getTree();
|
||||||
|
|
||||||
CommonTree sourceNode = (CommonTree) queryNode.getFirstChildWithType(CMISParser.SOURCE);
|
CommonTree sourceNode = (CommonTree) queryNode.getFirstChildWithType(CMISParser.SOURCE);
|
||||||
@@ -365,6 +366,14 @@ public class CMISQueryParser
|
|||||||
case CMISParser.PRED_FTS:
|
case CMISParser.PRED_FTS:
|
||||||
String ftsExpression = predicateNode.getChild(0).getText();
|
String ftsExpression = predicateNode.getChild(0).getText();
|
||||||
FTSQueryParser ftsQueryParser = new FTSQueryParser();
|
FTSQueryParser ftsQueryParser = new FTSQueryParser();
|
||||||
|
if (options.getQueryMode() == CMISQueryMode.CMS_STRICT)
|
||||||
|
{
|
||||||
|
// set default AND
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set default from the options
|
||||||
|
}
|
||||||
Selector selector;
|
Selector selector;
|
||||||
if (predicateNode.getChildCount() > 1)
|
if (predicateNode.getChildCount() > 1)
|
||||||
{
|
{
|
||||||
@@ -468,6 +477,11 @@ public class CMISQueryParser
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// in strict mode the ordered column must be selected
|
||||||
|
if ((options.getQueryMode() == CMISQueryMode.CMS_STRICT) && (match == null))
|
||||||
|
{
|
||||||
|
throw new CMISQueryException("Ordered column is not selected: " + qualifier + "." + columnName);
|
||||||
|
}
|
||||||
if (match == null)
|
if (match == null)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -489,12 +503,35 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
||||||
}
|
}
|
||||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(columnName, typeDef);
|
CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(columnName);
|
||||||
if (propDef == null)
|
if (propDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName);
|
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check there is a matching selector
|
||||||
|
|
||||||
|
if (options.getQueryMode() == CMISQueryMode.CMS_STRICT)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (Column column : columns)
|
||||||
|
{
|
||||||
|
if (column.getFunction().getName().equals(PropertyAccessor.NAME))
|
||||||
|
{
|
||||||
|
PropertyArgument pa = (PropertyArgument) column.getFunctionArguments().get(PropertyAccessor.ARG_PROPERTY);
|
||||||
|
if (pa.getPropertyName().equals(propDef.getPropertyId().getId()))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
throw new CMISQueryException("Ordered column is not selected: " + qualifier + "." + columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Function function = factory.getFunction(PropertyAccessor.NAME);
|
Function function = factory.getFunction(PropertyAccessor.NAME);
|
||||||
Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, propDef.isQueryable(), propDef.isOrderable(), selector.getAlias(), propDef
|
Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, propDef.isQueryable(), propDef.isOrderable(), selector.getAlias(), propDef
|
||||||
.getPropertyId().getId());
|
.getPropertyId().getId());
|
||||||
@@ -528,12 +565,35 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
||||||
}
|
}
|
||||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(columnName, typeDef);
|
CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(columnName);
|
||||||
if (propDef == null)
|
if (propDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName + " selector alias " + selector.getAlias());
|
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName + " selector alias " + selector.getAlias());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check there is a matching selector
|
||||||
|
|
||||||
|
if (options.getQueryMode() == CMISQueryMode.CMS_STRICT)
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for (Column column : columns)
|
||||||
|
{
|
||||||
|
if (column.getFunction().getName().equals(PropertyAccessor.NAME))
|
||||||
|
{
|
||||||
|
PropertyArgument pa = (PropertyArgument) column.getFunctionArguments().get(PropertyAccessor.ARG_PROPERTY);
|
||||||
|
if (pa.getPropertyName().equals(propDef.getPropertyId().getId()))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
throw new CMISQueryException("Ordered column is not selected: " + qualifier + "." + columnName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Function function = factory.getFunction(PropertyAccessor.NAME);
|
Function function = factory.getFunction(PropertyAccessor.NAME);
|
||||||
Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, propDef.isQueryable(), propDef.isOrderable(), selector.getAlias(), propDef
|
Argument arg = factory.createPropertyArgument(PropertyAccessor.ARG_PROPERTY, propDef.isQueryable(), propDef.isOrderable(), selector.getAlias(), propDef
|
||||||
.getPropertyId().getId());
|
.getPropertyId().getId());
|
||||||
@@ -545,7 +605,7 @@ public class CMISQueryParser
|
|||||||
orderColumn = factory.createColumn(function, functionArguments, alias);
|
orderColumn = factory.createColumn(function, functionArguments, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!orderColumn.isOrderable())
|
if (!orderColumn.isOrderable() || !orderColumn.isQueryable())
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Ordering is not support for " + orderColumn.getAlias());
|
throw new CMISQueryException("Ordering is not support for " + orderColumn.getAlias());
|
||||||
}
|
}
|
||||||
@@ -585,7 +645,10 @@ public class CMISQueryParser
|
|||||||
functionArguments.put(arg.getName(), arg);
|
functionArguments.put(arg.getName(), arg);
|
||||||
String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyId().getId() : definition.getPropertyId().getId();
|
String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyId().getId() : definition.getPropertyId().getId();
|
||||||
Column column = factory.createColumn(function, functionArguments, alias);
|
Column column = factory.createColumn(function, functionArguments, alias);
|
||||||
columns.add(column);
|
if (column.isQueryable())
|
||||||
|
{
|
||||||
|
columns.add(column);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -629,7 +692,10 @@ public class CMISQueryParser
|
|||||||
functionArguments.put(arg.getName(), arg);
|
functionArguments.put(arg.getName(), arg);
|
||||||
String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyId().getId() : definition.getPropertyId().getId();
|
String alias = (selector.getAlias().length() > 0) ? selector.getAlias() + "." + definition.getPropertyId().getId() : definition.getPropertyId().getId();
|
||||||
Column column = factory.createColumn(function, functionArguments, alias);
|
Column column = factory.createColumn(function, functionArguments, alias);
|
||||||
columns.add(column);
|
if (column.isQueryable())
|
||||||
|
{
|
||||||
|
columns.add(column);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -663,7 +729,7 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
throw new CMISQueryException("Type unsupported in CMIS queries: " + selector.getAlias());
|
||||||
}
|
}
|
||||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(columnName, typeDef);
|
CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(columnName);
|
||||||
if (propDef == null)
|
if (propDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName);
|
throw new CMISQueryException("Invalid column for " + typeDef.getQueryName() + "." + columnName);
|
||||||
@@ -682,6 +748,12 @@ public class CMISQueryParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column column = factory.createColumn(function, functionArguments, alias);
|
Column column = factory.createColumn(function, functionArguments, alias);
|
||||||
|
|
||||||
|
if (!column.isQueryable())
|
||||||
|
{
|
||||||
|
throw new CMISQueryException("Column is not queryable " + typeDef.getQueryName() + "." + columnName);
|
||||||
|
}
|
||||||
|
|
||||||
columns.add(column);
|
columns.add(column);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -691,9 +763,9 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
CommonTree functionNameNode = (CommonTree) functionNode.getChild(0);
|
CommonTree functionNameNode = (CommonTree) functionNode.getChild(0);
|
||||||
Function function = factory.getFunction(functionNameNode.getText());
|
Function function = factory.getFunction(functionNameNode.getText());
|
||||||
if(function == null)
|
if (function == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
||||||
}
|
}
|
||||||
Collection<ArgumentDefinition> definitions = function.getArgumentDefinitions().values();
|
Collection<ArgumentDefinition> definitions = function.getArgumentDefinitions().values();
|
||||||
Map<String, Argument> functionArguments = new LinkedHashMap<String, Argument>();
|
Map<String, Argument> functionArguments = new LinkedHashMap<String, Argument>();
|
||||||
@@ -731,7 +803,7 @@ public class CMISQueryParser
|
|||||||
int end = getStringPosition(query, rparenNode.getLine(), rparenNode.getCharPositionInLine());
|
int end = getStringPosition(query, rparenNode.getLine(), rparenNode.getCharPositionInLine());
|
||||||
|
|
||||||
String alias;
|
String alias;
|
||||||
if(function.getName().equals(Score.NAME))
|
if (function.getName().equals(Score.NAME))
|
||||||
{
|
{
|
||||||
alias = "SEARCH_SCORE";
|
alias = "SEARCH_SCORE";
|
||||||
// check no args
|
// check no args
|
||||||
@@ -813,7 +885,7 @@ public class CMISQueryParser
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(id, null);
|
CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(id);
|
||||||
if (propDef == null || !propDef.isQueryable())
|
if (propDef == null || !propDef.isQueryable())
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Column refers to unqueryable property " + definition.getName());
|
throw new CMISQueryException("Column refers to unqueryable property " + definition.getName());
|
||||||
@@ -875,24 +947,23 @@ public class CMISQueryParser
|
|||||||
String text = argNode.getChild(0).getText();
|
String text = argNode.getChild(0).getText();
|
||||||
text = text.substring(1, text.length() - 1);
|
text = text.substring(1, text.length() - 1);
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
if(text.endsWith("Z"))
|
if (text.endsWith("Z"))
|
||||||
{
|
{
|
||||||
builder.append(text.substring(0, text.length() - 1));
|
builder.append(text.substring(0, text.length() - 1));
|
||||||
builder.append("+0000");
|
builder.append("+0000");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(text.charAt( text.length() - 3) != ':')
|
if (text.charAt(text.length() - 3) != ':')
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Invalid datetime literal " + text);
|
throw new CMISQueryException("Invalid datetime literal " + text);
|
||||||
}
|
}
|
||||||
// remove TZ colon ....
|
// remove TZ colon ....
|
||||||
builder.append(text.substring(0, text.length() - 3));
|
builder.append(text.substring(0, text.length() - 3));
|
||||||
builder.append(text.substring(text.length() - 2, text.length()));
|
builder.append(text.substring(text.length() - 2, text.length()));
|
||||||
}
|
}
|
||||||
text = builder.toString();
|
text = builder.toString();
|
||||||
|
|
||||||
|
|
||||||
SimpleDateFormat df = CachingDateFormat.getCmisSqlDatetimeFormat();
|
SimpleDateFormat df = CachingDateFormat.getCmisSqlDatetimeFormat();
|
||||||
Date date;
|
Date date;
|
||||||
try
|
try
|
||||||
@@ -911,16 +982,16 @@ public class CMISQueryParser
|
|||||||
else if (argNode.getType() == CMISParser.BOOLEAN_LITERAL)
|
else if (argNode.getType() == CMISParser.BOOLEAN_LITERAL)
|
||||||
{
|
{
|
||||||
String text = argNode.getChild(0).getText();
|
String text = argNode.getChild(0).getText();
|
||||||
if(text.equalsIgnoreCase("TRUE") || text.equalsIgnoreCase("FALSE"))
|
if (text.equalsIgnoreCase("TRUE") || text.equalsIgnoreCase("FALSE"))
|
||||||
{
|
{
|
||||||
LiteralArgument arg = factory.createLiteralArgument(definition.getName(), DataTypeDefinition.TEXT, text);
|
LiteralArgument arg = factory.createLiteralArgument(definition.getName(), DataTypeDefinition.TEXT, text);
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Invalid boolean literal " + text);
|
throw new CMISQueryException("Invalid boolean literal " + text);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (argNode.getType() == CMISParser.LIST)
|
else if (argNode.getType() == CMISParser.LIST)
|
||||||
{
|
{
|
||||||
@@ -951,9 +1022,9 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
CommonTree functionNameNode = (CommonTree) argNode.getChild(0);
|
CommonTree functionNameNode = (CommonTree) argNode.getChild(0);
|
||||||
Function function = factory.getFunction(functionNameNode.getText());
|
Function function = factory.getFunction(functionNameNode.getText());
|
||||||
if(function == null)
|
if (function == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
||||||
}
|
}
|
||||||
Collection<ArgumentDefinition> definitions = function.getArgumentDefinitions().values();
|
Collection<ArgumentDefinition> definitions = function.getArgumentDefinitions().values();
|
||||||
Map<String, Argument> functionArguments = new LinkedHashMap<String, Argument>();
|
Map<String, Argument> functionArguments = new LinkedHashMap<String, Argument>();
|
||||||
@@ -1023,7 +1094,7 @@ public class CMISQueryParser
|
|||||||
alias = singleTableNode.getChild(1).getText();
|
alias = singleTableNode.getChild(1).getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForTable(tableName);
|
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeByQueryName(tableName);
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Type is unsupported in query: " + tableName);
|
throw new CMISQueryException("Type is unsupported in query: " + tableName);
|
||||||
@@ -1054,7 +1125,7 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
alias = singleTableNode.getChild(1).getText();
|
alias = singleTableNode.getChild(1).getText();
|
||||||
}
|
}
|
||||||
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeForTable(tableName);
|
CMISTypeDefinition typeDef = cmisDictionaryService.findTypeByQueryName(tableName);
|
||||||
if (typeDef == null)
|
if (typeDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Type is unsupported in query " + tableName);
|
throw new CMISQueryException("Type is unsupported in query " + tableName);
|
||||||
@@ -1098,14 +1169,14 @@ public class CMISQueryParser
|
|||||||
throw new CMISQueryException("No table with alias " + arg1.getSelector());
|
throw new CMISQueryException("No table with alias " + arg1.getSelector());
|
||||||
}
|
}
|
||||||
CommonTree functionNameNode = (CommonTree) joinConditionNode.getChild(1);
|
CommonTree functionNameNode = (CommonTree) joinConditionNode.getChild(1);
|
||||||
if(functionNameNode.getType()!= CMISParser.EQUALS)
|
if (functionNameNode.getType() != CMISParser.EQUALS)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Only Equi-join is supported " + functionNameNode.getText());
|
throw new CMISQueryException("Only Equi-join is supported " + functionNameNode.getText());
|
||||||
}
|
}
|
||||||
Function function = factory.getFunction(Equals.NAME);
|
Function function = factory.getFunction(Equals.NAME);
|
||||||
if(function == null)
|
if (function == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
throw new CMISQueryException("Unknown function: " + functionNameNode.getText());
|
||||||
}
|
}
|
||||||
PropertyArgument arg2 = buildColumnReference(Equals.ARG_RHS, (CommonTree) joinConditionNode.getChild(2), factory);
|
PropertyArgument arg2 = buildColumnReference(Equals.ARG_RHS, (CommonTree) joinConditionNode.getChild(2), factory);
|
||||||
if (!lhs.getSelectors().containsKey(arg2.getSelector()) && !rhs.getSelectors().containsKey(arg2.getSelector()))
|
if (!lhs.getSelectors().containsKey(arg2.getSelector()) && !rhs.getSelectors().containsKey(arg2.getSelector()))
|
||||||
@@ -1136,11 +1207,18 @@ public class CMISQueryParser
|
|||||||
{
|
{
|
||||||
qualifer = columnReferenceNode.getChild(1).getText();
|
qualifer = columnReferenceNode.getChild(1).getText();
|
||||||
}
|
}
|
||||||
CMISPropertyDefinition propDef = cmisDictionaryService.findProperty(cmisPropertyName, null);
|
CMISPropertyDefinition propDef = cmisDictionaryService.findPropertyByQueryName(cmisPropertyName);
|
||||||
if (propDef == null)
|
if (propDef == null)
|
||||||
{
|
{
|
||||||
throw new CMISQueryException("Unknown column/property " + cmisPropertyName);
|
throw new CMISQueryException("Unknown column/property " + cmisPropertyName);
|
||||||
}
|
}
|
||||||
|
if (options.getQueryMode() == CMISQueryMode.CMS_STRICT)
|
||||||
|
{
|
||||||
|
if (!propDef.isQueryable())
|
||||||
|
{
|
||||||
|
throw new CMISQueryException("Column is not queryable " + qualifer + "." + cmisPropertyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
return factory.createPropertyArgument(argumentName, propDef.isQueryable(), propDef.isOrderable(), qualifer, propDef.getPropertyId().getId());
|
return factory.createPropertyArgument(argumentName, propDef.isQueryable(), propDef.isOrderable(), qualifer, propDef.getPropertyId().getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.cmis.CMISDictionaryModel;
|
import org.alfresco.cmis.CMISDictionaryModel;
|
||||||
|
import org.alfresco.cmis.CMISPropertyDefinition;
|
||||||
import org.alfresco.cmis.CMISQueryException;
|
import org.alfresco.cmis.CMISQueryException;
|
||||||
import org.alfresco.cmis.CMISQueryOptions;
|
import org.alfresco.cmis.CMISQueryOptions;
|
||||||
import org.alfresco.cmis.CMISResultSet;
|
import org.alfresco.cmis.CMISResultSet;
|
||||||
@@ -305,6 +306,11 @@ public class QueryTest extends BaseCMISTest
|
|||||||
{
|
{
|
||||||
return testQuery(query, size, dump, returnPropertyName, returnType, shouldThrow, CMISQueryMode.CMS_STRICT);
|
return testQuery(query, size, dump, returnPropertyName, returnType, shouldThrow, CMISQueryMode.CMS_STRICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T> T testExtendedQuery(String query, int size, boolean dump, String returnPropertyName, T returnType, boolean shouldThrow)
|
||||||
|
{
|
||||||
|
return testQuery(query, size, dump, returnPropertyName, returnType, shouldThrow, CMISQueryMode.CMS_WITH_ALFRESCO_EXTENSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T> T testQuery(String query, int size, boolean dump, String returnPropertyName, T returnType, boolean shouldThrow, CMISQueryMode mode)
|
private <T> T testQuery(String query, int size, boolean dump, String returnPropertyName, T returnType, boolean shouldThrow, CMISQueryMode mode)
|
||||||
@@ -1345,9 +1351,9 @@ public class QueryTest extends BaseCMISTest
|
|||||||
|
|
||||||
public void testOrderBy()
|
public void testOrderBy()
|
||||||
{
|
{
|
||||||
String query = "SELECT cmis:objectId FROM cmis:document ORDER BY cmis:objectId";
|
CMISQueryOptions options = new CMISQueryOptions("SELECT cmis:objectId FROM cmis:folder ORDER BY cmis:objectId", rootNodeRef.getStoreRef());
|
||||||
CMISResultSet rs = cmisQueryService.query(query);
|
CMISResultSet rs = cmisQueryService.query(options);
|
||||||
// assertEquals(1, rs.getLength());
|
assertEquals(folder_count, rs.getLength());
|
||||||
for (CMISResultSetRow row : rs)
|
for (CMISResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
@@ -1355,9 +1361,9 @@ public class QueryTest extends BaseCMISTest
|
|||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
rs = null;
|
||||||
|
|
||||||
query = "SELECT cmis:objectId FROM cmis:document ORDER BY cmis:objectId ASC";
|
options = new CMISQueryOptions("SELECT cmis:objectId FROM cmis:folder ORDER BY cmis:objectId ASC", rootNodeRef.getStoreRef());
|
||||||
rs = cmisQueryService.query(query);
|
rs = cmisQueryService.query(options);
|
||||||
// assertEquals(1, rs.getLength());
|
assertEquals(folder_count, rs.getLength());
|
||||||
for (CMISResultSetRow row : rs)
|
for (CMISResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
@@ -1365,9 +1371,19 @@ public class QueryTest extends BaseCMISTest
|
|||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
rs = null;
|
||||||
|
|
||||||
query = "SELECT cmis:objectId FROM cmis:document ORDER BY cmis:objectId DESC";
|
options = new CMISQueryOptions("SELECT cmis:objectId FROM cmis:folder ORDER BY cmis:objectId DESC", rootNodeRef.getStoreRef());
|
||||||
rs = cmisQueryService.query(query);
|
rs = cmisQueryService.query(options);
|
||||||
// assertEquals(1, rs.getLength());
|
assertEquals(folder_count, rs.getLength());
|
||||||
|
for (CMISResultSetRow row : rs)
|
||||||
|
{
|
||||||
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
rs = null;
|
||||||
|
|
||||||
|
options = new CMISQueryOptions("SELECT D.cmis:objectId FROM cmis:folder D ORDER BY D.cmis:objectId DESC", rootNodeRef.getStoreRef());
|
||||||
|
rs = cmisQueryService.query(options);
|
||||||
|
assertEquals(folder_count, rs.getLength());
|
||||||
for (CMISResultSetRow row : rs)
|
for (CMISResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
@@ -1375,9 +1391,19 @@ public class QueryTest extends BaseCMISTest
|
|||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
rs = null;
|
||||||
|
|
||||||
query = "SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name IN ('company', 'home') ORDER BY MEEP ASC";
|
options = new CMISQueryOptions("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder ORDER BY MEEP ASC", rootNodeRef.getStoreRef());
|
||||||
rs = cmisQueryService.query(query);
|
rs = cmisQueryService.query(options);
|
||||||
// assertEquals(1, rs.getLength());
|
assertEquals(folder_count, rs.getLength());
|
||||||
|
for (CMISResultSetRow row : rs)
|
||||||
|
{
|
||||||
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
rs = null;
|
||||||
|
|
||||||
|
options = new CMISQueryOptions("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder ORDER BY MEEP ASC", rootNodeRef.getStoreRef());
|
||||||
|
rs = cmisQueryService.query(options);
|
||||||
|
assertEquals(folder_count, rs.getLength());
|
||||||
for (CMISResultSetRow row : rs)
|
for (CMISResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
@@ -1385,9 +1411,9 @@ public class QueryTest extends BaseCMISTest
|
|||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
rs = null;
|
||||||
|
|
||||||
query = "SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name IN ('company', 'home') ORDER BY MEEP DESC";
|
options = new CMISQueryOptions("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder ORDER BY MEEP DESC", rootNodeRef.getStoreRef());
|
||||||
rs = cmisQueryService.query(query);
|
rs = cmisQueryService.query(options);
|
||||||
// assertEquals(1, rs.getLength());
|
assertEquals(folder_count, rs.getLength());
|
||||||
for (CMISResultSetRow row : rs)
|
for (CMISResultSetRow row : rs)
|
||||||
{
|
{
|
||||||
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
System.out.println(row.getValue("cmis:objectId") + " Score " + row.getScore() + " " + row.getScores());
|
||||||
@@ -1395,26 +1421,36 @@ public class QueryTest extends BaseCMISTest
|
|||||||
rs.close();
|
rs.close();
|
||||||
rs = null;
|
rs = null;
|
||||||
|
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name = 'compan home') ORDER BY SCORE() DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name IN ('company', 'home') ORDER BY MEEEP DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name IN ('company', 'home') ORDER BY cmis:parentId DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId, cmis:parentId FROM cmis:folder ORDER BY cmis:parentId DESC", folder_count, false, "cmis:objectId", new String(), false);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder WHERE cmis:name IN ('company', 'home') ORDER BY cmis:notThere DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder as F WHERE cmis:name IN ('company', 'home') ORDER BY F.cmis:parentId DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
testQuery("SELECT SCORE() AS MEEP, cmis:objectId FROM cmis:folder F WHERE cmis:name IN ('company', 'home') ORDER BY F.cmis:notThere DESC", 1, false, "cmis:objectId", new String(), true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpperAndLower()
|
public void testUpperAndLower()
|
||||||
{
|
{
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'Folder 1'", 1, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'Folder 1'", 1, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'FOLDER 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'FOLDER 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'folder 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE cmis:name = 'folder 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'FOLDER 1'", 1, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'FOLDER 1'", 1, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'folder 1'", 1, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'folder 1'", 1, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'folder 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'folder 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'FOLDER 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'FOLDER 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'Folder 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) = 'Folder 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'Folder 1'", 0, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Lower(cmis:name) = 'Folder 1'", 0, false, "cmis:objectId", new String(), false);
|
||||||
|
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) <> 'FOLDER 1'", 9, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) <> 'FOLDER 1'", 9, false, "cmis:objectId", new String(), false);
|
||||||
|
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) <= 'FOLDER 1'", 2, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) <= 'FOLDER 1'", 2, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) < 'FOLDER 1'", 1, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) < 'FOLDER 1'", 1, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) >= 'FOLDER 1'", 9, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) >= 'FOLDER 1'", 9, false, "cmis:objectId", new String(), false);
|
||||||
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) > 'FOLDER 1'", 8, false, "cmis:objectId", new String(), false);
|
testExtendedQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) > 'FOLDER 1'", 8, false, "cmis:objectId", new String(), false);
|
||||||
|
|
||||||
|
testQuery("SELECT * FROM cmis:folder WHERE Upper(cmis:name) > 'FOLDER 1'", 8, false, "cmis:objectId", new String(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllSimpleTextPredicates()
|
public void testAllSimpleTextPredicates()
|
||||||
@@ -1536,7 +1572,15 @@ public class QueryTest extends BaseCMISTest
|
|||||||
CMISResultSetMetaData md = rs.getMetaData();
|
CMISResultSetMetaData md = rs.getMetaData();
|
||||||
assertNotNull(md.getQueryOptions());
|
assertNotNull(md.getQueryOptions());
|
||||||
CMISTypeDefinition typeDef = cmisDictionaryService.findType(CMISDictionaryModel.DOCUMENT_TYPE_ID);
|
CMISTypeDefinition typeDef = cmisDictionaryService.findType(CMISDictionaryModel.DOCUMENT_TYPE_ID);
|
||||||
assertEquals(typeDef.getPropertyDefinitions().size(), md.getColumnNames().length);
|
int count = 0;
|
||||||
|
for(CMISPropertyDefinition pdef : typeDef.getPropertyDefinitions().values())
|
||||||
|
{
|
||||||
|
if(pdef.isQueryable())
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(count, md.getColumnNames().length);
|
||||||
assertNotNull(md.getColumn(CMISDictionaryModel.PROP_OBJECT_ID));
|
assertNotNull(md.getColumn(CMISDictionaryModel.PROP_OBJECT_ID));
|
||||||
assertEquals(1, md.getSelectors().length);
|
assertEquals(1, md.getSelectors().length);
|
||||||
assertNotNull(md.getSelector(""));
|
assertNotNull(md.getSelector(""));
|
||||||
@@ -1637,6 +1681,7 @@ public class QueryTest extends BaseCMISTest
|
|||||||
CMISQueryOptions options = new CMISQueryOptions(
|
CMISQueryOptions options = new CMISQueryOptions(
|
||||||
"SELECT DOC.cmis:name AS cmis:name, \nLOWER(\tDOC.cmis:name \n), LOWER ( DOC.cmis:name ) AS Lcmis:name, UPPER ( DOC.cmis:name ) , UPPER(DOC.cmis:name) AS Ucmis:name, Score(), SCORE() AS S1, SCORE() AS SCORED FROM cmis:folder AS DOC",
|
"SELECT DOC.cmis:name AS cmis:name, \nLOWER(\tDOC.cmis:name \n), LOWER ( DOC.cmis:name ) AS Lcmis:name, UPPER ( DOC.cmis:name ) , UPPER(DOC.cmis:name) AS Ucmis:name, Score(), SCORE() AS S1, SCORE() AS SCORED FROM cmis:folder AS DOC",
|
||||||
rootNodeRef.getStoreRef());
|
rootNodeRef.getStoreRef());
|
||||||
|
options.setQueryMode(CMISQueryMode.CMS_WITH_ALFRESCO_EXTENSIONS);
|
||||||
CMISResultSet rs = cmisQueryService.query(options);
|
CMISResultSet rs = cmisQueryService.query(options);
|
||||||
|
|
||||||
CMISResultSetMetaData md = rs.getMetaData();
|
CMISResultSetMetaData md = rs.getMetaData();
|
||||||
|
Reference in New Issue
Block a user