001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.TablePrivilegesNode
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.error.StandardException;
025: import org.apache.derby.iapi.reference.SQLState;
026:
027: import org.apache.derby.impl.sql.execute.PrivilegeInfo;
028: import org.apache.derby.impl.sql.execute.TablePrivilegeInfo;
029: import org.apache.derby.iapi.services.io.FormatableBitSet;
030: import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
031:
032: import org.apache.derby.iapi.sql.depend.DependencyManager;
033: import org.apache.derby.iapi.sql.depend.Provider;
034: import org.apache.derby.iapi.sql.depend.ProviderInfo;
035: import org.apache.derby.iapi.sql.depend.ProviderList;
036: import org.apache.derby.iapi.sql.conn.ConnectionUtil;
037: import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
038: import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
039: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
040: import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
041: import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
042: import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;
043:
044: import java.util.ArrayList;
045: import java.util.List;
046:
047: /**
048: * This class represents a set of privileges on one table.
049: */
050: public class TablePrivilegesNode extends QueryTreeNode {
051: private boolean[] actionAllowed = new boolean[TablePrivilegeInfo.ACTION_COUNT];
052: private ResultColumnList[] columnLists = new ResultColumnList[TablePrivilegeInfo.ACTION_COUNT];
053: private FormatableBitSet[] columnBitSets = new FormatableBitSet[TablePrivilegeInfo.ACTION_COUNT];
054: private TableDescriptor td;
055: private List descriptorList;
056:
057: /**
058: * Add all actions
059: */
060: public void addAll() {
061: for (int i = 0; i < TablePrivilegeInfo.ACTION_COUNT; i++) {
062: actionAllowed[i] = true;
063: columnLists[i] = null;
064: }
065: } // end of addAll
066:
067: /**
068: * Add one action to the privileges for this table
069: *
070: * @param action The action type
071: * @param privilegeColumnList The set of privilege columns. Null for all columns
072: *
073: * @exception StandardException standard error policy.
074: */
075: public void addAction(int action,
076: ResultColumnList privilegeColumnList) {
077: actionAllowed[action] = true;
078: if (privilegeColumnList == null)
079: columnLists[action] = null;
080: else if (columnLists[action] == null)
081: columnLists[action] = privilegeColumnList;
082: else
083: columnLists[action].appendResultColumns(
084: privilegeColumnList, false);
085: } // end of addAction
086:
087: /**
088: * Bind.
089: *
090: * @param td The table descriptor
091: * @param isGrant grant if true; revoke if false
092: */
093: public void bind(TableDescriptor td, boolean isGrant)
094: throws StandardException {
095: this .td = td;
096:
097: for (int action = 0; action < TablePrivilegeInfo.ACTION_COUNT; action++) {
098: if (columnLists[action] != null)
099: columnBitSets[action] = columnLists[action]
100: .bindResultColumnsByName(td,
101: (DMLStatementNode) null);
102:
103: // Prevent granting non-SELECT privileges to views
104: if (td.getTableType() == TableDescriptor.VIEW_TYPE
105: && action != TablePrivilegeInfo.SELECT_ACTION)
106: if (actionAllowed[action])
107: throw StandardException.newException(
108: SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED, td
109: .getQualifiedName());
110: }
111:
112: if (isGrant && td.getTableType() == TableDescriptor.VIEW_TYPE) {
113: bindPrivilegesForView(td);
114: }
115: }
116:
117: /**
118: * @return PrivilegeInfo for this node
119: */
120: public PrivilegeInfo makePrivilegeInfo() {
121: return new TablePrivilegeInfo(td, actionAllowed, columnBitSets,
122: descriptorList);
123: }
124:
125: /**
126: * Retrieve all the underlying stored dependencies such as table(s),
127: * view(s) and routine(s) descriptors which the view depends on.
128: * This information is then passed to the runtime to determine if
129: * the privilege is grantable to the grantees by this grantor at
130: * execution time.
131: *
132: * Go through the providers regardless who the grantor is since
133: * the statement cache may be in effect.
134: *
135: * @param td the TableDescriptor to check
136: *
137: * @exception StandardException standard error policy.
138: */
139: private void bindPrivilegesForView(TableDescriptor td)
140: throws StandardException {
141: LanguageConnectionContext lcc = getLanguageConnectionContext();
142: DataDictionary dd = lcc.getDataDictionary();
143: ViewDescriptor vd = dd.getViewDescriptor(td);
144: DependencyManager dm = dd.getDependencyManager();
145: ProviderInfo[] pis = dm.getPersistentProviderInfos(vd);
146: this .descriptorList = new ArrayList();
147:
148: int siz = pis.length;
149: for (int i = 0; i < siz; i++) {
150: try {
151: Provider provider = (Provider) pis[i]
152: .getDependableFinder().getDependable(
153: pis[i].getObjectId());
154: if (provider == null) {
155: throw StandardException.newException(
156: SQLState.LANG_OBJECT_NOT_FOUND, "OBJECT",
157: pis[i].getObjectId());
158: }
159:
160: if (provider instanceof TableDescriptor
161: || provider instanceof ViewDescriptor
162: || provider instanceof AliasDescriptor) {
163: descriptorList.add(provider);
164: }
165: } catch (java.sql.SQLException ex) {
166: throw StandardException.plainWrapException(ex);
167: }
168: }
169: }
170:
171: }
|