001/* 002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.storage.dbs; 020 021import static org.nuxeo.ecm.core.storage.dbs.DBSDocument.KEY_ACL; 022import static org.nuxeo.ecm.core.storage.dbs.DBSDocument.KEY_ACP; 023 024import java.util.regex.Matcher; 025import java.util.regex.Pattern; 026 027import org.nuxeo.ecm.core.query.sql.NXQL; 028import org.nuxeo.ecm.core.storage.QueryOptimizer; 029 030/** 031 * DBS-specific query optimizer. 032 * <p> 033 * Knows how reference prefixes are computed, especially for the ACL case which has a storage structure different than 034 * what the NXQL syntax suggests. 035 * 036 * @since 9.3 037 */ 038public class DBSQueryOptimizer extends QueryOptimizer { 039 040 protected static final Pattern CORRELATED_WILDCARD_SPLIT = Pattern.compile("(([^*]+)/(\\*\\d+))/(.*)"); 041 042 protected static final Pattern CORRELATED_ECM_TAG = Pattern.compile(NXQL.ECM_TAG + "/\\*\\d+"); 043 044 protected static final String CORRELATED_ECM_TAG_IMPLICIT = "__ecm_tag_correlated__"; 045 046 @Override 047 public String getCorrelatedWildcardPrefix(String name) { 048 if (name.startsWith(NXQL.ECM_TAG)) { 049 if (name.equals(NXQL.ECM_TAG)) { 050 // naked ecm:tag are always correlated with themselves 051 return CORRELATED_ECM_TAG_IMPLICIT; 052 } else if (CORRELATED_ECM_TAG.matcher(name).matches()) { 053 return name; 054 } else { 055 return ""; 056 } 057 } 058 Matcher m = CORRELATED_WILDCARD_SPLIT.matcher(name); 059 if (!m.matches()) { 060 return ""; 061 } 062 String start = m.group(2); 063 String wildcard = m.group(3); 064 String end = m.group(4); 065 if (start.equals(NXQL.ECM_ACL)) { 066 if (end.equals(NXQL.ECM_ACL_NAME)) { 067 return KEY_ACP + '/' + wildcard; 068 } else { 069 return KEY_ACP + '/' + wildcard + '/' + KEY_ACL + '/' + wildcard; 070 } 071 } else { 072 return m.group(1); 073 } 074 } 075 076}